FS2_Open
Open source remastering of the Freespace 2 engine
mainhallmenu.cpp
Go to the documentation of this file.
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 the
6  * source.
7  *
8  */
9 
10 #include <stdlib.h>
11 #include <limits.h>
12 
13 #include "anim/animplay.h"
14 #include "anim/packunpack.h"
15 #include "cmdline/cmdline.h"
16 #include "freespace2/freespace.h"
17 #include "gamehelp/contexthelp.h"
19 #include "gamesnd/eventmusic.h"
20 #include "gamesnd/gamesnd.h"
21 #include "globalincs/alphacolors.h"
22 #include "graphics/generic.h"
23 #include "io/key.h"
24 #include "io/mouse.h"
25 #include "io/timer.h"
26 #include "menuui/fishtank.h"
27 #include "menuui/mainhallmenu.h"
28 #include "menuui/playermenu.h"
29 #include "menuui/snazzyui.h"
31 #include "network/multi.h"
32 #include "network/multi_voice.h"
33 #include "network/multiui.h"
34 #include "network/multiutil.h"
35 #include "palman/palman.h"
36 #include "parse/parselo.h"
37 #include "parse/scripting.h"
38 #include "playerman/player.h"
39 #include "popup/popup.h"
40 #include "sound/audiostr.h"
41 
42 #ifndef NDEBUG
43 #include "cutscene/movie.h"
44 #include "mission/missionload.h"
45 #endif
46 
47 
48 // A reference to io/keycontrol.cpp
49 extern void game_process_cheats(int k);
50 
51 // ----------------------------------------------------------------------------
52 // MAIN HALL DATA DEFINES
53 //
54 #define MISC_ANIM_MODE_LOOP 0 // loop the animation
55 #define MISC_ANIM_MODE_HOLD 1 // play to the end and hold the animation
56 #define MISC_ANIM_MODE_TIMED 2 // uses timestamps to determine when a finished anim should be checked again
57 #define NUM_REGIONS 7 // (6 + 1 for multiplayer equivalent of campaign room)
58 #define MAIN_HALL_MAX_CHEAT_LEN 40 // cheat buffer length (also maximum cheat length)
59 
61 
62 static main_hall_defines *Main_hall = NULL;
63 
64 static int Main_hall_music_index = -1;
65 
66 int Vasudan_funny = 0;
68 
70 
71 // ----------------------------------------------------------------------------
72 // MISC interface data
73 //
74 // is the main hall inited (for reentrancy)
76 
77 // handle to the playing music
79 
80 // background bitmap handle
82 
83 // background bitmap dimensions
86 
87 // background bitmap mask handle
89 
90 // bitmap struct for th background mask bitmap
92 
93 // actual data for the background mask bitmap
95 
97 
98 
99 // ----------------------------------------------------------------------------
100 // MOUSE clicking stuff
101 //
102 // indicates whether a right click occured
104 
105 // use this to cycle through the selectable regions instead of the mouse's current region
107 
108 // use this to determine how long the cursor has to linger on a region before it starts playing
109 #define MAIN_HALL_REGION_LINGER 175 // in ms
111 
112 // handle any right clicks which may have occured
114 
115 
116 // ----------------------------------------------------------------------------
117 // RANDOM intercom sounds
118 //
119 
120 // next random intercom sound to play
122 
123 // delay for the next intercom sound
125 
126 // handle to any playing instance of a random intercom sound
128 
129 // handle any details related to random intercom sounds
131 
132 
133 // ----------------------------------------------------------------------------
134 // MISC animations
135 //
136 
137 // the misc animations themselves
139 
140 // render all playing misc animations
141 void main_hall_render_misc_anims(float frametime, bool over_doors);
142 
143 
144 // ----------------------------------------------------------------------------
145 // DOOR animations (not all of these are doors anymore, but they're doorlike _regions_)
146 //
147 #define DOOR_TEXT_X 100
148 #define DOOR_TEXT_Y 450
149 
150 // the door animations themselves
152 
153 // render all playing door animations
154 void main_hall_render_door_anims(float frametime);
155 
156 
157 // ----------------------------------------------------------------------------
158 // SNAZZY MENU stuff
159 //
160 #define NUM_MAIN_HALL_MAX_REGIONS 20
161 
162 // region mask #'s (identifiers)
163 #define EXIT_REGION 0
164 #define BARRACKS_REGION 1
165 #define READY_ROOM_REGION 2
166 #define TECH_ROOM_REGION 3
167 #define OPTIONS_REGION 4
168 #define CAMPAIGN_ROOM_REGION 5
169 #define MULTIPLAYER_REGION 10
170 #define LOAD_MISSION_REGION 11
171 #define QUICK_START_REGION 12
172 #define SKILL_LEVEL_REGION 13
173 #define SCRIPT_REGION 14
174 #define START_REGION 15
175 
177  int mask;
178  char *name;
179 };
180 
182  { EXIT_REGION, "Exit" },
183  { BARRACKS_REGION, "Barracks" },
184  { READY_ROOM_REGION, "Readyroom" },
185  { TECH_ROOM_REGION, "Techroom" },
186  { OPTIONS_REGION, "Options" },
187  { CAMPAIGN_ROOM_REGION, "Campaigns" },
188  { MULTIPLAYER_REGION, "Multiplayer" },
189  { LOAD_MISSION_REGION, "Load Mission" },
190  { QUICK_START_REGION, "Quickstart" },
191  { SKILL_LEVEL_REGION, "Skilllevel" },
192  { SCRIPT_REGION, "Script" },
193  { START_REGION, "Start" },
194  { -1, NULL }
195 };
196 
197 // all the menu regions in the main hall
199 
200 // region over which the mouse is currently residing, or -1 if over no region
201 // NOTE : you should nevery change this directly. Always use main_hall_handle_mouse_location(int)
202 // to do this. Otherwise, the door opening and closing animations will get screwed up
204 
205 // set this to skip a frame
207 
208 // do any necessary processing based upon the mouse location
209 void main_hall_handle_mouse_location(int cur_region);
210 
211 // if the mouse has moved off of the currently active region, handle the anim accordingly
212 void main_hall_mouse_release_region(int region);
213 
214 // if the mouse has moved on this region, handle it accordingly
215 void main_hall_mouse_grab_region(int region);
216 
217 
218 // ----------------------------------------------------------------------------
219 // SOUND data / handlers
220 // -
221 
222 // toaster oven room sound idex
223 #define TOASTER_REGION 3
224 
225 // everyone's favorite desk guardian
226 #define ALLENDER_REGION 4
227 
228 // handles to the sound instances of the doors opening/closing
230 
231 // sound handle for looping ambient sound
233 
234 // cull any door sounds that have finished playing
236 
237 // handle starting, stopping and reversing "door" animations
239 
240 // to determine if we should continue playing sounds and random animations
241 static int Main_hall_paused = 0;
242 
243 
244 // ----------------------------------------------------------------------------
245 // warning/notification messages
246 //
247 #define MAIN_HALL_NOTIFY_TIME 3500
248 
249 // timestamp for the notification messages
251 
252 // text to display as the current notification message
254 
255 // set the current notification string and the associated timestamp
256 void main_hall_set_notify_string(const char *str);
257 
258 // handle any drawing, culling, etc of notification messages
259 void main_hall_notify_do();
260 
261 
262 // ----------------------------------------------------------------------------
263 // MISC functions
264 //
265 
266 // upper _RIGHT_ corner for the version text
267 #define MAIN_HALL_VERSION_X 630
268 #define MAIN_HALL_VERSION_Y 467
269 
270 // main hall help overlay ID
272 
273 // blit the freespace version #
275 
276 // blit any necessary tooltips
278 
279 // shader for behind tooltips
281 
282 // num pixels shader is above/below tooltip text
283 static int Main_hall_default_tooltip_padding[GR_NUM_RESOLUTIONS] = {
284  4, // GR_640
285  7, // GR_1024
286 };
287 static int Main_hall_f1_text_frame = 0;
288 static int F1_text_done = 0;
289 
290 // "press f1" for help stuff
291 #define MAIN_HALL_HELP_TIME 5000
294 
295 
296 // ----------------------------------------------------------------------------
297 // VOICE RECORDING STUFF
298 //
299 
300 // are we currently recording voice?
301 int Recording = 0;
302 
303 /*
304  * Called when multiplayer clicks on the ready room door. May pop up dialog depending on network
305  * connection status and errors
306  */
308 {
309  int error;
310 
311  error = psnet_get_network_status();
312  switch( error ) {
314  popup( PF_USE_AFFIRMATIVE_ICON | 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));
315  break;
317  popup( PF_USE_AFFIRMATIVE_ICON | PF_NO_NETWORKING, 1, POPUP_OK, XSTR( "Winsock is not installed. You must have TCP/IP and Winsock installed to play multiplayer FreeSpace.", 361));
318  break;
321  popup( PF_USE_AFFIRMATIVE_ICON | PF_NO_NETWORKING, 1, POPUP_OK, XSTR( "TCP/IP protocol not found. This protocol is required for multiplayer FreeSpace.", 1602));
322  }
323  break;
325  popup( PF_USE_AFFIRMATIVE_ICON | 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));
326  break;
328  popup( PF_USE_AFFIRMATIVE_ICON | 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));
329  break;
330 
331  case NETWORK_ERROR_NONE:
332  default:
333  break;
334  }
335 
336  // if our selected protocol is not active
339  popup( PF_USE_AFFIRMATIVE_ICON | PF_NO_NETWORKING, 1, POPUP_OK, XSTR( "You have selected TCP/IP for multiplayer FreeSpace, but the TCP socket is already in use. Check for another instance and/or use the \"-port <port_num>\" command line option to select an available port.", 1604));
340  } else {
341  popup( PF_USE_AFFIRMATIVE_ICON | 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));
342  }
343  return;
344  }
345 
346  if (error != NETWORK_ERROR_NONE) {
347  return;
348  }
349 
350  // 7/9/98 -- MWA. Deal with the connection speed issue. make a call to the multiplayer code to
351  // determine is a valid connection setting exists
353  popup( PF_USE_AFFIRMATIVE_ICON | 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) );
354  return;
355  }
356 
357  // go to parallax online
358  if (Om_tracker_flag) {
361  } else {
362  // go to the regular join game screen
364  }
365 
366  // select protocol
368 }
369 
370 
371 // blit some small color indicators to show whether ships.tbl and weapons.tbl are valid
372 // green == valid, red == invalid.
373 // ships.tbl will be on the left, weapons.tbl on the right
375 {
376  // blit ship table status
379 
380  // blit weapon table status
383 }
384 
389 {
390  char *ret = popup_input(0, XSTR("Enter mission name.\n\n* This will destroy all legitimate progress in this campaign. *", 1605));
391 
392  // yay
393  if (ret != NULL) {
395  }
396 }
397 
398 // -------------------------------------------------------------------------------------------------------------------
399 // FUNCTION DEFINITIONS BEGIN
400 //
401 
407 void main_hall_init(const SCP_string &main_hall_name)
408 {
409  BM_TYPE bg_type;
410  if (Main_hall_inited) {
411  return;
412  }
413 
414  int idx;
415  SCP_string main_hall_to_load;
416 
417  // reparse the table here if the relevant cmdline flag is set
420  }
421 
422  // sanity checks
423  if (Main_hall_defines.size() == 0) {
424  Error(LOCATION, "No main halls were loaded to initialize.");
425  } else if (main_hall_name == "") {
426  Warning(LOCATION, "main_hall_init() was passed a blank main hall name; loading first available main hall.");
427  main_hall_get_name(main_hall_to_load, 0);
428  } else if (main_hall_get_pointer(main_hall_name) == NULL) {
429  Warning(LOCATION, "Tried to load a main hall called '%s', but it does not exist; loading first available main hall.", main_hall_name.c_str());
430  main_hall_get_name(main_hall_to_load, 0);
431  } else {
432  main_hall_to_load = main_hall_name;
433  }
434 
435  // if we're switching to a different mainhall we may need to change music
436  if (main_hall_get_music_index(main_hall_get_index(main_hall_to_load)) != Main_hall_music_index) {
437  main_hall_stop_music(true);
438  }
439 
440  // create the snazzy interface and load up the info from the table
442 
443  // assign the proper main hall data
444  Main_hall = main_hall_get_pointer(main_hall_to_load);
445  Assertion(Main_hall != NULL, "Failed to obtain pointer to main hall '%s'; get a coder!\n", main_hall_to_load.c_str());
446 
447  // check if we have to change the ready room's description
448  if(Main_hall->default_readyroom) {
450  Main_hall->regions[2].description = XSTR( "Multiplayer - Start or join a multiplayer game", 359);
451  } else {
452  Main_hall->regions[2].description = XSTR( "Ready room - Start or continue a campaign", 355);
453  }
454  }
455 
456  // Read the menu regions from mainhall.tbl
458  for (it = Main_hall->regions.begin(); Main_hall->regions.end() != it; ++it) {
459  snazzy_menu_add_region(&Main_hall_region[it - Main_hall->regions.begin()], it->description.c_str(), it->mask, it->key, -1);
460  }
461 
462  // init tooltip shader // nearly black
463  gr_create_shader(&Main_hall_tooltip_shader, 5, 5, 5, 168);
464 
465  // are we funny?
467  if (!stricmp(Main_hall->bitmap.c_str(), "vhall")) {
468  Main_hall->door_sounds.at(OPTIONS_REGION).at(0) = SND_VASUDAN_BUP;
469  Main_hall->door_sounds.at(OPTIONS_REGION).at(1) = SND_VASUDAN_BUP;
470 
471  // set head anim. hehe
472  Main_hall->door_anim_name.at(OPTIONS_REGION) = "vhallheads";
473 
474  // set the background
475  Main_hall->bitmap = "vhallhead";
476  } else if (!stricmp(Main_hall->bitmap.c_str(), "2_vhall")) {
477  Main_hall->door_sounds.at(OPTIONS_REGION).at(0) = SND_VASUDAN_BUP;
478  Main_hall->door_sounds.at(OPTIONS_REGION).at(1) = SND_VASUDAN_BUP;
479 
480  // set head anim. hehe
481  Main_hall->door_anim_name.at(OPTIONS_REGION) = "2_vhallheads";
482 
483  // set the background
484  Main_hall->bitmap = "2_vhallhead";
485  }
486  }
487 
488  Main_hall_bitmap_w = -1;
489  Main_hall_bitmap_h = -1;
490 
491  // load the background bitmap
492  Main_hall_bitmap = bm_load(Main_hall->bitmap);
493  if (Main_hall_bitmap < 0) {
494  nprintf(("General","WARNING! Couldn't load main hall background bitmap %s\n", Main_hall->bitmap.c_str()));
495  } else {
497  }
498  bg_type = bm_get_type(Main_hall_bitmap);
499 
500  Main_hall_mask_w = -1;
501  Main_hall_mask_h = -1;
502 
503  // load the mask
504  Main_hall_mask = bm_load(Main_hall->mask);
505  if (Main_hall_mask < 0) {
506  nprintf(("General","WARNING! Couldn't load main hall background mask %s\n", Main_hall->mask.c_str()));
507  if (gr_screen.res == 0) {
508  Error(LOCATION,"Could not load in main hall mask '%s'!\n\n(This error most likely means that you are missing required 640x480 interface art.)", Main_hall->mask.c_str());
509  } else {
510  Error(LOCATION,"Could not load in main hall mask '%s'!\n\n(This error most likely means that you are missing required 1024x768 interface art.)", Main_hall->mask.c_str());
511  }
512  } else {
513  // get a pointer to bitmap by using bm_lock(), so we can feed it to he snazzy menu system
514  Main_hall_mask_bitmap = bm_lock(Main_hall_mask, 8, BMP_AABITMAP);
515  Main_hall_mask_data = (ubyte*)Main_hall_mask_bitmap->data;
517  }
518 
519  // make sure the zoom area is completely within the background bitmap
520  if (Main_hall->zoom_area_width > Main_hall_bitmap_w) {
521  Main_hall->zoom_area_width = Main_hall_bitmap_w;
522  }
523  if (Main_hall->zoom_area_height > Main_hall_bitmap_h) {
525  }
526 
527  // get the default value for tooltip padding if necessary
528  if (Main_hall->tooltip_padding == -1) {
529  Main_hall->tooltip_padding = Main_hall_default_tooltip_padding[gr_get_resolution_class(Main_hall_bitmap_w, Main_hall_bitmap_h)];
530  }
531 
532  // In case we're re-entering the mainhall
533  Main_hall_misc_anim.clear();
534 
535  // load up the misc animations, and nullify all the delay timestamps for the misc animations
536  for (idx = 0; idx < Main_hall->num_misc_animations; idx++) {
537  generic_anim temp_anim;
538  generic_anim_init(&temp_anim, Main_hall->misc_anim_name.at(idx));
539  Main_hall_misc_anim.push_back(temp_anim);
540  Main_hall_misc_anim.at(idx).ani.bg_type = bg_type;
541  if (generic_anim_stream(&Main_hall_misc_anim.at(idx)) == -1) {
542  nprintf(("General","WARNING!, Could not load misc %s anim in main hall\n",Main_hall->misc_anim_name.at(idx).c_str()));
543  } else {
544  // start paused
545  if (Main_hall->misc_anim_modes.at(idx) == MISC_ANIM_MODE_HOLD)
546  Main_hall_misc_anim.at(idx).direction |= GENERIC_ANIM_DIRECTION_NOLOOP;
547  }
548 
549  // null out the delay timestamps
550  Main_hall->misc_anim_delay.at(idx).at(0) = -1;
551 
552  // start paused
553  Main_hall->misc_anim_paused.at(idx) = true;
554  }
555 
556  // In case we're re-entering the mainhall
557  Main_hall_door_anim.clear();
558 
559  // load up the door animations
560  for (idx = 0; idx < Main_hall->num_door_animations; idx++) {
561  generic_anim temp_anim;
562  generic_anim_init(&temp_anim, Main_hall->door_anim_name.at(idx));
563  Main_hall_door_anim.push_back(temp_anim);
564  Main_hall_door_anim.at(idx).ani.bg_type = bg_type;
565  if (generic_anim_stream(&Main_hall_door_anim.at(idx)) == -1) {
566  nprintf(("General","WARNING!, Could not load door anim %s in main hall\n",Main_hall->door_anim_name.at(idx).c_str()));
567  } else {
568  Main_hall_door_anim.at(idx).direction = GENERIC_ANIM_DIRECTION_BACKWARDS | GENERIC_ANIM_DIRECTION_NOLOOP;
569  }
570  }
571 
572  // load in help overlay bitmap
573  if (!Main_hall->help_overlay_name.empty()) {
575  } else if (main_hall_id() == 0) {
577  } else {
579  }
581 
582  // check to see if the "very first pilot" flag is set, and load the overlay if so
583  if (!F1_text_done) {
584  if (Main_hall_f1_text_frame == 0) {
586  } else {
587  F1_text_done = 1;
588  }
589  }
590 
592 
593  // initialize door sound handles
594  Main_hall_door_sound_handles.clear();
595  for (idx = 0; idx < Main_hall->num_door_animations; idx++) {
596  Main_hall_door_sound_handles.push_back(-1);
597  }
598 
599  // skip the first frame
601 
602  // initialize the music
604 
605  // initialize the main hall notify text
607 
608  // initialize the random intercom sound stuff
612 
613  // set the placement of the mouse cursor (start at the ready room)
616 
617  Main_hall_inited = 1;
618 
619  // determine if we have a right click
621 }
622 
629 {
630 #if defined(NDEBUG)
631  int choice;
632 
633  // stop music first
634  main_hall_stop_music(true);
636  choice = popup( PF_NO_NETWORKING | PF_BODY_BIG, 2, POPUP_NO, POPUP_YES, XSTR( "Exit Game?", 365));
637  if (choice == 1) {
639  } else {
642  }
643 #else
645 #endif
646 }
647 
653 void main_hall_do(float frametime)
654 {
655  int code, key, snazzy_action, region_action = -1;
657 
658  // set the screen scale to the main hall's dimensions
660 
661  // need to ensure ambient is playing, since it may be stopped by a playing movie
663 
664  // handle any random intercom sound details
666 
667  // handle any mouse clicks
669 
670  // handle any sound details
672 
673  // do any campaign load failure handling
675 
676  // process any keypresses/mouse events
677  snazzy_action = -1;
678  code = snazzy_menu_do(Main_hall_mask_data, Main_hall_mask_w, Main_hall_mask_h, (int)Main_hall->regions.size(), Main_hall_region, &snazzy_action, 1, &key);
679 
680  if (key) {
681  game_process_cheats(key);
682 
683  Main_hall_cheat += (char) key_to_ascii(key);
686  }
687 
688  int cur_frame;
689  float anim_time;
690  bool cheat_anim_found, cheat_found = false;
691 
692  for (int c_idx = 0; c_idx < (int) Main_hall->cheat.size(); c_idx++) {
693  cheat_anim_found = false;
694 
695  if(Main_hall_cheat.find(Main_hall->cheat.at(c_idx)) != SCP_string::npos) {
696  cheat_found = true;
697  // switch animations
698 
699  for (int idx = 0; idx < Main_hall->num_misc_animations; idx++) {
700  if (Main_hall->misc_anim_name.at(idx) == Main_hall->cheat_anim_from.at(c_idx)) {
701  Main_hall->misc_anim_name.at(idx) = Main_hall->cheat_anim_to.at(c_idx);
702 
703  cur_frame = Main_hall_misc_anim.at(idx).current_frame;
704  anim_time = Main_hall_misc_anim.at(idx).anim_time;
705 
706  generic_anim_unload(&Main_hall_misc_anim.at(idx));
707  generic_anim_init(&Main_hall_misc_anim.at(idx), Main_hall->misc_anim_name.at(idx));
708 
709  if (generic_anim_stream(&Main_hall_misc_anim.at(idx)) == -1) {
710  nprintf(("General","WARNING! Could not load misc %s anim in main hall\n", Main_hall->misc_anim_name.at(idx).c_str()));
711  } else {
712  // start paused
713  if (Main_hall->misc_anim_modes.at(idx) == MISC_ANIM_MODE_HOLD)
714  Main_hall_misc_anim.at(idx).direction |= GENERIC_ANIM_DIRECTION_NOLOOP;
715  }
716 
717  Main_hall_misc_anim.at(idx).current_frame = cur_frame;
718  Main_hall_misc_anim.at(idx).anim_time = anim_time;
719 
720  // null out the delay timestamps
721  Main_hall->misc_anim_delay.at(idx).at(0) = -1;
722 
723  cheat_anim_found = true;
724  break;
725  }
726  }
727 
728  if (!cheat_anim_found) {
729  for (int idx = 0; idx < Main_hall->num_door_animations; idx++) {
730  if (Main_hall->door_anim_name.at(idx) == Main_hall->cheat_anim_from.at(c_idx)) {
731  Main_hall->door_anim_name.at(idx) = Main_hall->cheat_anim_to.at(c_idx);
732 
733  cur_frame = Main_hall_door_anim.at(idx).current_frame;
734  anim_time = Main_hall_door_anim.at(idx).anim_time;
735 
736  generic_anim_unload(&Main_hall_door_anim.at(idx));
737  generic_anim_init(&Main_hall_door_anim.at(idx), Main_hall->door_anim_name.at(idx));
738 
739  if (generic_anim_stream(&Main_hall_door_anim.at(idx)) == -1) {
740  nprintf(("General","WARNING! Could not load door anim %s in main hall\n", Main_hall->door_anim_name.at(idx).c_str()));
741  } else {
742  Main_hall_door_anim.at(idx).direction = GENERIC_ANIM_DIRECTION_BACKWARDS | GENERIC_ANIM_DIRECTION_NOLOOP;
743  }
744 
745  Main_hall_door_anim.at(idx).current_frame = cur_frame;
746  Main_hall_door_anim.at(idx).anim_time = anim_time;
747 
748  cheat_anim_found = true;
749  break;
750  }
751  }
752  }
753 
754  if (!cheat_anim_found) {
755  // Note: This can also happen if the cheat triggers a second time since the animations are already switched at that point.
756  nprintf(("General", "Could not find animation '%s' for cheat '%s'!", Main_hall->cheat_anim_from.at(c_idx).c_str(), Main_hall->cheat.at(c_idx).c_str()));
757  }
758  }
759  }
760 
761  if(cheat_found) {
762  // Found a cheat, clear the buffer.
763 
764  Main_hall_cheat = "";
765  }
766  }
767 
768  switch(key) {
769  case KEY_ENTER:
770  snazzy_action = SNAZZY_CLICKED;
771  break;
772  case KEY_F3:
775  break;
776  #ifndef NDEBUG
777  case KEY_1:
778  // no soup for you!
779  movie_play("endprt2b.mve");
780  break;
781  case KEY_2:
782  // no soup for you!
783  movie_play_two("endprt2a.mve", "endprt2b.mve");
784  break;
785  case KEY_3:
787  break;
788  #endif
789  }
790 
791  // do any processing based upon what happened to the snazzy menu
792  switch (snazzy_action) {
793  case SNAZZY_OVER:
794  for (it = Main_hall->regions.begin(); Main_hall->regions.end() != it; ++it) {
795  if (it->mask == code) {
796  main_hall_handle_mouse_location(it - Main_hall->regions.begin());
797  break;
798  }
799  }
800 
801  break;
802 
803  case SNAZZY_CLICKED:
804  if (code == ESC_PRESSED) {
805  region_action = ESC_PRESSED;
806  } else {
807  if (code == -1) {
808  // User didn't click on a valid button, just ignore the event
809  break;
810  }
811 
812  for (it = Main_hall->regions.begin(); Main_hall->regions.end() != it; ++it) {
813  if (it->mask == code) {
814  region_action = it->action;
815  break;
816  }
817  }
818 
819  if (region_action == -1) {
820  Error(LOCATION, "Region %d doesn't have an action!", code);
821  } else if (region_action == START_REGION) {
823  region_action = MULTIPLAYER_REGION;
824  } else {
825  region_action = READY_ROOM_REGION;
826  }
827  }
828  }
829 
830  switch (region_action) {
831  // clicked on the exit region
832  case EXIT_REGION:
835  break;
836 
837  // clicked on the readyroom region
838  case READY_ROOM_REGION:
839  // Make sure we aren't in multi mode.
842 
845  break;
846 
847  // clicked on the tech room region
848  case TECH_ROOM_REGION:
851  break;
852 
853  // clicked on the options region
854  case OPTIONS_REGION:
857  break;
858 
859  // clicked on the campaign toom region
863  break;
864 
865  // clicked on the multiplayer region
866  case MULTIPLAYER_REGION:
867  // Make sure we are in multi mode.
870 
872 
873  // NOTE : this isn't a great thing to be calling this anymore. But we'll leave it for now
875  break;
876 
877  // load mission key was pressed
878  case LOAD_MISSION_REGION:
879  break;
880 
881  // quick start a game region
882  case QUICK_START_REGION:
883  #if !defined(NDEBUG)
884  if (Num_recent_missions > 0) {
886  } else {
887  if (mission_load_up_campaign()) {
888  main_hall_set_notify_string(XSTR( "Campaign file is currently unavailable", 1606));
889  }
891  }
894  #endif
895  break;
896 
897  // clicked on the barracks region
898  case BARRACKS_REGION:
901  break;
902 
903  // increate the skill level
904  case SKILL_LEVEL_REGION:
905  char temp[100];
907  sprintf(temp, XSTR( "Skill level set to %s.", 370), Skill_level_names(Game_skill_level));
909  break;
910 
911  // escape was pressed
912  case ESC_PRESSED:
913  // if there is a help overlay active, then don't quit the game - just kill the overlay
917  } else { // kill the overlay
919  }
920  break;
921 
922  // custom action
923  case SCRIPT_REGION:
924  const char *lua = it->lua_action.c_str();
925  bool success = Script_system.EvalString(lua, NULL, NULL, lua);
926  if(!success)
927  Warning(LOCATION, "mainhall '+Door Action / $Script' failed to evaluate \"%s\"; check your syntax", lua);
928  break;
929  } // END switch (code)
930 
931  // if the escape key wasn't pressed handle any mouse position related events
932  if (code != ESC_PRESSED) {
933  main_hall_handle_mouse_location((region_action == -1 ? -1 : it - Main_hall->regions.begin()));
934  }
935  break;
936 
937  default:
939  break;
940  } // END switch (snazzy_action)
941 
944  }
945 
946  // draw the background bitmap
947  gr_reset_clip();
949  if (Main_hall_bitmap >= 0) {
951  gr_bitmap(0, 0, GR_RESIZE_MENU);
952  }
953 
954  // render misc animations
955  main_hall_render_misc_anims(frametime, false);
956 
957  // render door animtions
958  main_hall_render_door_anims(frametime);
959 
960  // render misc animations (over doors)
961  main_hall_render_misc_anims(frametime, true);
962 
963  // blit any appropriate tooltips
965 
966  // fishtank
968 
969  // draw any pending notification messages
971 
972  // process any help "hit f1" timestamps and display any messages if necessary
973  if (!F1_text_done) {
975  }
976 
977  // blit help overlay if active
979 
980  // blit the freespace version #
982 
983  // blit ship and weapon table status
984 #ifndef NDEBUG
986 #endif
987 
988  gr_flip();
990 
991  // see if we have a missing campaign and force the player to select a new campaign if so
992  extern bool Campaign_room_no_campaigns;
993  if ( !(Player->flags & PLAYER_FLAGS_IS_MULTI) && Campaign_file_missing && !Campaign_room_no_campaigns ) {
994  int rc = popup(0, 3, XSTR("Go to Campaign Room", 1607), XSTR("Select another pilot", 1608), XSTR("Exit Game", 1609), XSTR("The currently active campaign cannot be found. Please select another...", 1600));
995 
996  switch (rc) {
997  case 0:
999  break;
1000 
1001  case 1:
1003  break;
1004 
1005  case 2:
1007  break;
1008 
1009  default:
1011  break;
1012  }
1013  }
1014 
1015  // maybe run the player tips popup
1017 
1018  // if we were supposed to skip a frame, then stop doing it after 1 frame
1019  if (Main_hall_frame_skip) {
1021  }
1022 }
1023 
1028 {
1029  int idx, s_idx;
1030 
1031  if (!Main_hall_inited) {
1032  return;
1033  }
1034 
1035  // unload the main hall bitmap
1036  if (Main_hall_bitmap != -1) {
1038  }
1039 
1040  // unload any bitmaps
1041  if (Main_hall_mask >= 0) {
1042  // make sure we unlock the mask bitmap so it can be unloaded
1045  }
1046 
1047  // free up any (possibly) playing misc animation handles
1048  for (idx = 0; idx < Main_hall->num_misc_animations; idx++) {
1049  if (Main_hall_misc_anim.at(idx).num_frames > 0) {
1050  generic_anim_unload(&Main_hall_misc_anim.at(idx));
1051  }
1052  }
1053 
1054  // free up any (possibly) playing door animation handles
1055  for (idx = 0; idx < Main_hall->num_door_animations; idx++) {
1056  if (Main_hall_door_anim.at(idx).num_frames > 0) {
1057  generic_anim_unload(&Main_hall_door_anim.at(idx));
1058  }
1059  }
1060 
1061  // stop any playing door sounds
1062  for (idx = 0; idx < Main_hall->num_door_animations-2; idx++) {
1063  if ( (Main_hall_door_sound_handles.at(idx) != -1) && snd_is_playing(Main_hall_door_sound_handles.at(idx)) ) {
1064  snd_stop(Main_hall_door_sound_handles.at(idx));
1065  Main_hall_door_sound_handles.at(idx) = -1;
1066  }
1067  }
1068 
1069  // stop any playing misc animation sounds
1070  for (idx = 0; idx < Main_hall->num_misc_animations; idx++) {
1071  // if this goes wrong, the int cast could overflow
1072  Assert(Main_hall->misc_anim_special_sounds.at(idx).size() < INT_MAX);
1073 
1074  for (s_idx = 0; s_idx < (int)Main_hall->misc_anim_special_sounds.at(idx).size(); s_idx++) {
1075  if (snd_is_playing(Main_hall->misc_anim_special_sounds.at(idx).at(s_idx))) {
1076  snd_stop(Main_hall->misc_anim_special_sounds.at(idx).at(s_idx));
1077  }
1078  }
1079  }
1080 
1081  // close any snazzy menu details
1083 
1084  // no fish
1085  fishtank_stop();
1086 
1087  // unpause
1088  Main_hall_paused = 0;
1089 
1090  // not inited anymore
1091  Main_hall_inited = 0;
1092 }
1093 
1100 int main_hall_get_music_index(int main_hall_num)
1101 {
1102  main_hall_defines *hall;
1103  int index;
1104 
1105  if (main_hall_num < 0) {
1106  return -1;
1107  }
1108 
1109  hall = &Main_hall_defines.at(main_hall_num).at(main_hall_get_resolution_index(main_hall_num));
1110 
1111  // Goober5000 - try substitute first
1113  if ( (index >= 0) && (Spooled_music[index].flags & SMF_VALID) ) {
1114  return index;
1115  }
1116 
1117  // now try regular
1119  if ( (index >= 0) && (Spooled_music[index].flags & SMF_VALID) ) {
1120  return index;
1121  }
1122 
1123  return -1;
1124 }
1125 
1130 {
1131  char *filename;
1132 
1133  // start a looping ambient sound
1135 
1136  // if we have selected no music, then don't do this
1138  return;
1139  }
1140 
1141  // already playing?
1142  if (Main_hall_music_handle >= 0) {
1143  return;
1144  }
1145 
1146  // get music
1147  Main_hall_music_index = main_hall_get_music_index(main_hall_id());
1148  if (Main_hall_music_index < 0) {
1149  nprintf(("Warning", "No music file exists to play music at the main menu!\n"));
1150  return;
1151  }
1152 
1153  filename = Spooled_music[Main_hall_music_index].filename;
1154  Assert(filename != NULL);
1155 
1156  // get handle
1158  if (Main_hall_music_handle < 0) {
1159  nprintf(("Warning", "No music file exists to play music at the main menu!\n"));
1160  return;
1161  }
1162 
1164 }
1165 
1169 void main_hall_stop_music(bool fade)
1170 {
1171  if (Main_hall_music_handle != -1) {
1174  }
1175 }
1176 
1182 void main_hall_render_misc_anims(float frametime, bool over_doors)
1183 {
1184  std::deque<bool> group_anims_weve_checked;
1185  int idx, s_idx, jdx;
1186 
1187  // render all misc animations
1188  for (idx = 0; idx < Main_hall->num_misc_animations; idx++) {
1189  // give it a spot in the vector
1190  group_anims_weve_checked.push_back(false);
1191 
1192  // render it
1193  if (Main_hall_misc_anim.at(idx).num_frames > 0 && Main_hall->misc_anim_over_doors.at(idx) == over_doors) {
1194  // animation is paused
1195  if (Main_hall->misc_anim_paused.at(idx)) {
1196  // if the timestamp is -1, then regenerate it
1197  if (Main_hall->misc_anim_delay.at(idx).at(0) == -1) {
1198  int regen_idx = -1;
1199 
1200  // if this is part of a group, we should do additional checking
1201  if (Main_hall->misc_anim_group.at(idx) >= 0) {
1202 
1203  // make sure we haven't already checked it
1204  if (group_anims_weve_checked.at(idx) == false) {
1205  SCP_vector<int> group_indexes; //stores indexes of which anims are part of a group
1206  bool all_neg1 = true;
1207 
1208  // okay... now we need to make sure all anims in this group are paused and -1
1209  for (jdx = 0; jdx < Main_hall->num_misc_animations; jdx++) {
1210  if (Main_hall->misc_anim_group.at(jdx) == Main_hall->misc_anim_group.at(idx)) {
1211  Assert(group_anims_weve_checked.size() < INT_MAX);
1212  if ((int)group_anims_weve_checked.size() <= jdx) {
1213  group_anims_weve_checked.push_back(true);
1214  } else {
1215  group_anims_weve_checked.at(jdx) = true;
1216  }
1217 
1218  group_indexes.push_back(jdx);
1219 
1220  if (!Main_hall->misc_anim_paused.at(jdx) || Main_hall->misc_anim_delay.at(jdx).at(0) != -1) {
1221  all_neg1 = false;
1222  }
1223  }
1224  }
1225 
1226  // if the entire group is paused and off, pick a random one to regenerate
1227  if (all_neg1) {
1228  Assert(group_indexes.size() < INT_MAX);
1229  regen_idx = group_indexes[rand() % (int)group_indexes.size()];
1230  }
1231  }
1232  } else { // not part of a group, so just handle this index
1233  regen_idx = idx;
1234  }
1235 
1236  // reset it to some random value (based on MIN and MAX) and continue
1237  if (regen_idx >= 0) {
1238  int min = Main_hall->misc_anim_delay.at(regen_idx).at(1);
1239  int max = Main_hall->misc_anim_delay.at(regen_idx).at(2);
1240  Main_hall->misc_anim_delay.at(regen_idx).at(0) = timestamp(min + (int) (frand() * (max - min)));
1241  }
1242 
1243  // if the timestamp is not -1 and has popped, play the anim and make the timestamp -1
1244  } else if (timestamp_elapsed(Main_hall->misc_anim_delay.at(idx).at(0))) {
1245  Main_hall->misc_anim_paused.at(idx) = false;
1246  Main_hall_misc_anim.at(idx).current_frame = 0;
1247  Main_hall_misc_anim.at(idx).anim_time = 0.0;
1248 
1249  // kill the timestamp
1250  Main_hall->misc_anim_delay.at(idx).at(0) = -1;
1251 
1252  // reset the "should be playing" flags
1253  Assert(Main_hall->misc_anim_sound_flag.at(idx).size() < INT_MAX);
1254  for (s_idx = 0; s_idx < (int)Main_hall->misc_anim_sound_flag.at(idx).size(); s_idx++) {
1255  Main_hall->misc_anim_sound_flag.at(idx).at(s_idx) = 0;
1256  }
1257  }
1258  } else { // animation is not paused
1259  Assert(Main_hall->misc_anim_special_sounds.at(idx).size() < INT_MAX);
1260  for (s_idx = 0; s_idx < (int)Main_hall->misc_anim_special_sounds.at(idx).size(); s_idx++) {
1261  // if we've passed the trigger point, then play the sound and break out of the loop
1262  if ( (Main_hall_misc_anim.at(idx).current_frame >= Main_hall->misc_anim_special_trigger.at(idx).at(s_idx))
1263  && !Main_hall->misc_anim_sound_flag.at(idx).at(s_idx) ) {
1264  Main_hall->misc_anim_sound_flag.at(idx).at(s_idx) = 1;
1265 
1266  // if the sound is already playing, then kill it.
1267  // This is a pretty safe thing to do since we can assume that by the time we get to this point again,
1268  // the sound will have been long finished
1269  if (snd_is_playing(Main_hall->misc_anim_special_sounds.at(idx).at(s_idx))) {
1270  snd_stop(Main_hall->misc_anim_special_sounds.at(idx).at(s_idx));
1271  }
1272 
1273  int sound = Main_hall->misc_anim_special_sounds.at(idx).at(s_idx);
1274 
1275  // Check if the sound is valid
1276  if (sound >= 0)
1277  {
1278  // play the sound
1279  snd_play(&Snds_iface[sound],Main_hall->misc_anim_sound_pan.at(idx));
1280  }
1281  break;
1282  }
1283  }
1284 
1285  // animation has reached the last frame
1286  if (Main_hall_misc_anim.at(idx).current_frame == Main_hall_misc_anim.at(idx).num_frames - 1) {
1287  Main_hall->misc_anim_delay.at(idx).at(0) = -1;
1288 
1289  // this helps the above code reset the timers
1290  // MISC_ANIM_MODE_HOLD simply stops on the last frame, so we don't care
1291  // MISC_ANIM_MODE_LOOPED just loops so we don't care either
1292  if (Main_hall->misc_anim_modes.at(idx) == MISC_ANIM_MODE_TIMED) {
1293  Main_hall->misc_anim_paused.at(idx) = true;
1294  }
1295  // don't reset sound for MISC_ANIM_MODE_HOLD
1296  if (Main_hall->misc_anim_modes.at(idx) != MISC_ANIM_MODE_HOLD) {
1297  // reset the "should be playing" flags
1298  Assert(Main_hall->misc_anim_sound_flag.at(idx).size() < INT_MAX);
1299  for (s_idx = 0; s_idx < (int)Main_hall->misc_anim_sound_flag.at(idx).size(); s_idx++) {
1300  Main_hall->misc_anim_sound_flag.at(idx).at(s_idx) = 0;
1301  }
1302  }
1303  }
1304 
1305  // actually render it
1306  if (Main_hall_frame_skip || Main_hall_paused) {
1307  frametime = 0;
1308  }
1309  generic_anim_render(&Main_hall_misc_anim.at(idx), frametime, Main_hall->misc_anim_coords.at(idx).at(0), Main_hall->misc_anim_coords.at(idx).at(1), true);
1310  }
1311  }
1312  }
1313 }
1314 
1319 void main_hall_render_door_anims(float frametime)
1320 {
1321  int idx;
1322 
1323  // render all door animations
1324  Assert(Main_hall_door_anim.size() < INT_MAX);
1325  for (idx = 0; idx < (int)Main_hall_door_anim.size(); idx++) {
1326  if (Main_hall_door_anim.at(idx).num_frames > 0) {
1327  // first pair : coords of where to play a given door anim
1328  // second pair : center of a given door anim in windowed mode
1329  generic_anim_render(&Main_hall_door_anim.at(idx), frametime, Main_hall->door_anim_coords.at(idx).at(0), Main_hall->door_anim_coords.at(idx).at(1), true);
1330  }
1331  }
1332 }
1333 
1339 {
1340  if (Main_hall_frame_skip) {
1341  return;
1342  }
1343 
1344  if (cur_region >= (int) Main_hall->regions.size()) {
1345  // MWA -- inserted return since Int3() was tripped when hitting L from main menu.
1346  return;
1347  }
1348 
1349  // if the mouse is now over a resgion
1350  if (cur_region != -1) {
1351  // if we're still over the same region we were last frame, check stuff
1352  if (cur_region == Main_hall_mouse_region) {
1353  // if we have a linger timestamp set and it has expired, then get moving
1355  main_hall_mouse_grab_region(cur_region);
1356 
1357  // release the region linger stamp
1359  }
1360  } else {
1361  // if we're currently on another region, release it
1362  if ( (Main_hall_mouse_region != -1) && (cur_region != Main_hall_mouse_region) ) {
1364  }
1365 
1366  // set the linger time
1367  if (Main_hall_region_linger_stamp == -1) {
1368  Main_hall_mouse_region = cur_region;
1370  }
1371  }
1372  } else { // if it was over a region but isn't anymore, release that region
1373  if (Main_hall_mouse_region != -1) {
1376 
1377  // release the region linger timestamp
1379  }
1380  }
1381 }
1382 
1388 {
1389  if (Main_hall_frame_skip) {
1390  return;
1391  }
1392  // don't do anything if there are no animations to play
1393  else if (region >= (int) Main_hall_door_anim.size()) {
1394  return;
1395  }
1396 
1397  // run backwards and stop at the first frame
1398  Main_hall_door_anim.at(region).direction = GENERIC_ANIM_DIRECTION_BACKWARDS | GENERIC_ANIM_DIRECTION_NOLOOP;
1399 
1400  // check for door sounds, ignoring the OPTIONS_REGION (which isn't a door)
1401  if (Main_hall_door_anim.at(region).num_frames > 0) {
1402  // don't stop the toaster oven or microwave regions from playing all the way through
1403  if (Main_hall_door_sound_handles.at(region) != -1) {
1404  snd_stop(Main_hall_door_sound_handles.at(region));
1405  }
1406 
1407  int sound = Main_hall->door_sounds.at(region).at(1);
1408 
1409  if (sound >= 0)
1410  {
1411  Main_hall_door_sound_handles.at(region) = snd_play(&Snds_iface[sound], Main_hall->door_sound_pan.at(region));
1412  }
1413 
1414  // TODO: track current frame
1415  snd_set_pos(Main_hall_door_sound_handles.at(region), &Snds_iface[SND_MAIN_HALL_DOOR_CLOSE],
1416  (float)((Main_hall_door_anim.at(region).keyframe) ? Main_hall_door_anim.at(region).keyframe :
1417  Main_hall_door_anim.at(region).num_frames - Main_hall_door_anim.at(region).current_frame) /
1418  (float)Main_hall_door_anim.at(region).num_frames, 1);
1419  }
1420 }
1421 
1427 {
1428  if (Main_hall_frame_skip) {
1429  return;
1430  }
1431  // don't do anything if there are no animations to play
1432  else if (region >= (int) Main_hall_door_anim.size()) {
1433  return;
1434  }
1435 
1436  // run forwards
1437  Main_hall_door_anim.at(region).direction = GENERIC_ANIM_DIRECTION_FORWARDS;
1438  // stay on last frame if we have no keyframe
1439  if (!Main_hall_door_anim.at(region).keyframe) {
1440  Main_hall_door_anim.at(region).direction += GENERIC_ANIM_DIRECTION_NOLOOP;
1441  }
1442 
1443  // check for opening/starting sounds
1444  // kill the currently playing sounds if necessary
1445  if (Main_hall_door_sound_handles.at(region) != -1) {
1446  snd_stop(Main_hall_door_sound_handles.at(region));
1447  }
1448 
1449 
1450  int sound = Main_hall->door_sounds.at(region).at(0);
1451 
1452  if (sound >= 0)
1453  {
1454  Main_hall_door_sound_handles.at(region) = snd_play(&Snds_iface[sound],Main_hall->door_sound_pan.at(region));
1455  }
1456 
1457  // start the sound playing at the right spot relative to the completion of the animation
1458  if ( (Main_hall_door_anim.at(region).num_frames > 0) && (Main_hall_door_anim.at(region).current_frame != -1) ) {
1459  snd_set_pos(Main_hall_door_sound_handles.at(region),&Snds_iface[SND_MAIN_HALL_DOOR_OPEN],
1460  (float)Main_hall_door_anim.at(region).current_frame / (float)Main_hall_door_anim.at(region).num_frames,1);
1461  }
1462 }
1463 
1468 {
1469  int new_region;
1470 
1471  if (Main_hall_frame_skip) {
1472  return;
1473  }
1474 
1475  // check to see if the button has been clicked
1476  if (!Main_hall_right_click) {
1478  // cycle through the available regions
1479  if (Main_hall_last_clicked_region == (int) Main_hall_door_anim.size() - 1) {
1480  new_region = 0;
1481  } else {
1482  new_region = Main_hall_last_clicked_region + 1;
1483  }
1484 
1485  // set the position of the mouse cursor and the newly clicked region
1486  int mx = Main_hall->door_anim_coords.at(new_region).at(2);
1487  int my = Main_hall->door_anim_coords.at(new_region).at(3);
1488  gr_resize_screen_pos( &mx, &my, NULL, NULL, GR_RESIZE_MENU );
1489 
1490  if (mx < 0) {
1491  mx = 0;
1492  }
1493  if (mx >= gr_screen.max_w) {
1494  mx = gr_screen.max_w - 1;
1495  }
1496  if (my < 0) {
1497  my = 0;
1498  }
1499  if (my >= gr_screen.max_h) {
1500  my = gr_screen.max_h - 1;
1501  }
1502 
1503  mouse_set_pos( mx, my );
1504 
1505  main_hall_handle_mouse_location(new_region);
1506  Main_hall_last_clicked_region = new_region;
1507 
1508  // set the mouse as being clicked
1510  }
1511  // set the mouse as being unclicked
1514  }
1515 }
1516 
1521 {
1522  int idx;
1523  // 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
1524  Assert(Main_hall_door_sound_handles.size() < INT_MAX);
1525  for (idx = 0; idx < (int)Main_hall_door_sound_handles.size(); idx++) {
1526  if ( (Main_hall_door_sound_handles.at(idx) != -1) && !snd_is_playing(Main_hall_door_sound_handles.at(idx)) ) {
1527  Main_hall_door_sound_handles.at(idx) = -1;
1528  }
1529  }
1530 }
1531 
1536 {
1537  if (Main_hall->num_random_intercom_sounds <= 0)
1538  {
1539  // If there are no intercom sounds then just skip this section
1540  return;
1541  }
1542 
1543  // if we have no timestamp for the next random sound, then set on
1546  (float)(Main_hall->intercom_delay.at(Main_hall_next_intercom_sound).at(1)
1547  - Main_hall->intercom_delay.at(Main_hall_next_intercom_sound).at(0))) );
1548  }
1549 
1550  // if the there is no sound playing
1551  if (Main_hall_intercom_sound_handle == -1) {
1552  if (Main_hall_paused) {
1553  return;
1554  }
1555 
1556  // if the timestamp has popped, play a sound
1559 
1560  // Check if the sound is valid
1561  if (sound >= 0)
1562  {
1563  // play the sound
1565 
1566  // unset the timestamp
1568  }
1569 
1570  // unset the timestamp
1572  }
1573  } else { // if the sound is playing
1574  // if the sound has finished, set the timestamp and continue
1576  // increment the next sound
1579  } else {
1581  }
1582 
1583  // set the timestamp
1585  (float)(Main_hall->intercom_delay.at(Main_hall_next_intercom_sound).at(1)
1586  - Main_hall->intercom_delay.at(Main_hall_next_intercom_sound).at(0))) );
1587 
1588  // release the sound handle
1590  }
1591  }
1592 }
1593 
1598 void main_hall_set_notify_string(const char *str)
1599 {
1602 }
1603 
1608 {
1609  // check to see if we should try and do something
1610  if (Main_hall_notify_stamp != -1) {
1611  // if the text time has expired
1615  } else {
1616  int w,h;
1617 
1618  int old_font = gr_get_current_fontnum();
1619 
1621  gr_set_font(Main_hall->font);
1622 
1625 
1626  gr_set_font(old_font);
1627  }
1628  }
1629 }
1630 
1635 {
1636  int play_ambient_loop = 0;
1637 
1638  if (Main_hall_paused) {
1639  return;
1640  }
1641 
1642  if (Main_hall_ambient_loop == -1) {
1643  play_ambient_loop = 1;
1644  } else {
1646  play_ambient_loop = 1;
1647  }
1648  }
1649 
1650  if (play_ambient_loop) {
1652  }
1653 }
1654 
1659 {
1660  if (Main_hall_ambient_loop != -1) {
1663  }
1664 }
1665 
1672 {
1673  if (Main_hall_ambient_loop >= 0) {
1675  }
1676 }
1677 
1682 {
1683  int w, h;
1684  char version_string[100];
1685 
1686  // format the version string
1687  get_version_string(version_string, sizeof(version_string));
1688 
1689  int old_font = gr_get_current_fontnum();
1690  gr_set_font(Main_hall->font);
1691 
1692  // get the length of the string
1693  gr_get_string_size(&w,&h,version_string);
1694 
1695  // print the string near the lower left corner
1697  gr_string(5, gr_screen.max_h_unscaled_zoomed - (h * 2 + 6), version_string, GR_RESIZE_MENU_ZOOMED);
1698 
1699  gr_set_font(old_font);
1700 }
1701 
1706 {
1707  int w, h;
1708 
1709  // if we're over no region - don't blit anything
1710  if (Main_hall_mouse_region < 0) {
1711  return;
1712  }
1713 
1714  if (Main_hall_mouse_region >= (int) Main_hall->regions.size()) {
1715  Error(LOCATION, "Missing region description for index %d!\n", Main_hall_mouse_region);
1716  }
1717 
1718  // set the color and blit the string
1720  const char* desc = Main_hall->regions[Main_hall_mouse_region].description.c_str();
1721 
1722  int old_font = gr_get_current_fontnum();
1723  gr_set_font(Main_hall->font);
1724  // get the width of the string
1725  gr_get_string_size(&w, &h, desc);
1726  int text_y;
1727  if (Main_hall->region_yval == -1) {
1729  } else {
1730  text_y = Main_hall->region_yval;
1731  }
1732  int shader_y = text_y - (Main_hall->tooltip_padding); // subtract more to pull higher
1733 
1734  gr_set_shader(&Main_hall_tooltip_shader);
1736 
1738  gr_string((gr_screen.max_w_unscaled - w)/2, text_y, desc, GR_RESIZE_MENU);
1739 
1740  gr_set_font(old_font);
1741  }
1742 }
1743 
1748 {
1749  int w, h;
1750  char str[255];
1751 
1752  // if the timestamp has popped, don't do anything
1753  if (Main_hall_help_stamp == -1) {
1754  return;
1755  }
1756 
1757  // if the timestamp has popped, advance frame
1759  Main_hall_f1_text_frame++;
1760  }
1761 
1762  int old_font = gr_get_current_fontnum();
1763  gr_set_font(Main_hall->font);
1764 
1765  // otherwise print out the message
1766  strcpy_s(str, XSTR( "Press F1 for help", 371));
1767  gr_get_string_size(&w, &h, str);
1768 
1769  int y_anim_offset = Main_hall_f1_text_frame;
1770 
1771  // if anim is off the screen finally, stop altogether
1772  if ( (y_anim_offset >= (2*Main_hall->tooltip_padding) + h) || (help_overlay_active(Main_hall_overlay_id)) ) {
1773  Main_hall_f1_text_frame = -1;
1774  Main_hall_help_stamp = -1;
1775  F1_text_done = 1;
1776  return;
1777  }
1778 
1779  // set the color and print out text and shader
1781  gr_set_shader(&Main_hall_tooltip_shader);
1782  gr_shade(0, 0, gr_screen.max_w_unscaled_zoomed, (2*Main_hall->tooltip_padding) + h - y_anim_offset, GR_RESIZE_MENU_ZOOMED);
1783  gr_string((gr_screen.max_w_unscaled_zoomed - w)/2, Main_hall->tooltip_padding - y_anim_offset, str, GR_RESIZE_MENU_ZOOMED);
1784 
1785  gr_set_font(old_font);
1786 }
1787 
1796 {
1797  unsigned int i;
1798 
1799  for (i = 0; i < Main_hall_defines.size(); i++) {
1800  if (Main_hall_defines.at(i).at(0).name == name_to_find) {
1801  return &Main_hall_defines.at(i).at(main_hall_get_resolution_index(i));
1802  }
1803  }
1804  return NULL;
1805 }
1806 
1815 int main_hall_get_index(const SCP_string &name_to_find)
1816 {
1817  unsigned int i;
1818 
1819  for (i = 0; i < Main_hall_defines.size(); i++) {
1820  if (Main_hall_defines.at(i).at(0).name == name_to_find) {
1821  return i;
1822  }
1823  }
1824  return -1;
1825 }
1826 
1827 int main_hall_get_resolution_index(int main_hall_num)
1828 {
1829  unsigned int i;
1830  float aspect_ratio = (float)gr_screen.center_w / (float)gr_screen.center_h;
1831 
1832  for (i = Main_hall_defines.at(main_hall_num).size() - 1; i >= 1; i--) {
1833  main_hall_defines* m = &Main_hall_defines.at(main_hall_num).at(i);
1834  if (gr_screen.center_w >= m->min_width && gr_screen.center_h >= m->min_height && aspect_ratio >= m->min_aspect_ratio) {
1835  return i;
1836  }
1837  }
1838  return 0;
1839 }
1840 
1842 {
1843  if (index>=Main_hall_defines.size()) {
1844  name = "";
1845  } else {
1846  name = Main_hall_defines.at(index).at(0).name;
1847  }
1848 }
1849 
1851 {
1852  if (Main_hall==NULL) {
1853  return -1;
1854  } else {
1855  return Main_hall_overlay_id;
1856  }
1857 }
1858 
1860 {
1861  if (Main_hall==NULL) {
1862  return -1;
1863  } else {
1864  return Main_hall->help_overlay_resolution_index;
1865  }
1866 }
1867 
1868 // what main hall we're on
1870 {
1871  if (Main_hall==NULL) {
1872  return -1;
1873  } else {
1874  return main_hall_get_index(Main_hall->name);
1875  }
1876 }
1877 
1878 // CommanderDJ - helper function for initialising intercom sounds vectors based on number of sounds
1879 // To be called after num_intercom_sounds has been parsed
1881 {
1882  int idx;
1883 
1885  // we could be reparsing with a different number of intercom sounds, so clear these and reinitialise
1886  m.intercom_delay.clear();
1887  m.intercom_sounds.clear();
1888  m.intercom_sound_pan.clear();
1889  }
1890 
1892 
1893  for (idx = 0; idx < m.num_random_intercom_sounds; idx++) {
1894  // intercom_delay
1895  m.intercom_delay.push_back(temp);
1896 
1897  // each delay has a min and a max
1898  m.intercom_delay.at(idx).push_back(0);
1899  m.intercom_delay.at(idx).push_back(0);
1900 
1901  // intercom_sounds
1902  m.intercom_sounds.push_back(-1);
1903 
1904  // intercom_sound_pan
1905  m.intercom_sound_pan.push_back(0);
1906  }
1907 }
1908 
1916 {
1917  int idx;
1918 
1920  // we could be reparsing with a different number of misc anims, so clear these and reinitialise
1921  m.misc_anim_name.clear();
1922  m.misc_anim_delay.clear();
1923  m.misc_anim_paused.clear();
1924  m.misc_anim_group.clear();
1925  m.misc_anim_coords.clear();
1926  m.misc_anim_modes.clear();
1927  m.misc_anim_sound_pan.clear();
1928  m.misc_anim_special_sounds.clear();
1929  m.misc_anim_special_trigger.clear();
1930  m.misc_anim_sound_flag.clear();
1931  }
1932 
1934  SCP_string temp_string;
1935 
1936  for (idx = 0; idx < m.num_misc_animations; idx++) {
1937 
1938  // misc_anim_name
1939  m.misc_anim_name.push_back(temp_string);
1940 
1941  // misc_anim_delay
1942  m.misc_anim_delay.push_back(temp);
1943 
1944  // -1 default for the first entry, 0 for the others
1945  m.misc_anim_delay.at(idx).push_back(-1);
1946  m.misc_anim_delay.at(idx).push_back(0);
1947  m.misc_anim_delay.at(idx).push_back(0);
1948 
1949  // misc_anim_paused
1950  m.misc_anim_paused.push_back(1); // default is paused
1951 
1952  // misc_anim_group
1953  m.misc_anim_group.push_back(-1);
1954 
1955  // misc_anim_coords
1956  m.misc_anim_coords.push_back(temp);
1957 
1958  m.misc_anim_coords.at(idx).push_back(0);
1959  m.misc_anim_coords.at(idx).push_back(0);
1960 
1961  // misc_anim_modes
1962  m.misc_anim_modes.push_back(MISC_ANIM_MODE_LOOP);
1963 
1964  // misc_anim_sound_pan
1965  m.misc_anim_sound_pan.push_back(0.0f);
1966 
1967  // misc_anim_special_sounds
1968  // parse_sound_list deals with the rest of the initialisation for this one
1969  m.misc_anim_special_sounds.push_back(temp);
1970 
1971  // misc_anim_special_trigger
1972  m.misc_anim_special_trigger.push_back(temp);
1973 
1974  m.misc_anim_special_trigger.at(idx).push_back(0);
1975 
1976  // misc_anim_sound_flag
1977  m.misc_anim_sound_flag.push_back(temp);
1978  }
1979 }
1980 
1988 {
1989  int idx;
1990 
1992  /* since we could be reparsing with a different number of door
1993  anims, clear these and reinitialise. */
1994  m.door_anim_name.clear();
1995  m.door_anim_coords.clear();
1996  m.door_sounds.clear();
1997  m.door_sound_pan.clear();
1998  }
1999 
2001  SCP_string temp_string;
2002 
2003  for (idx = 0; idx < m.num_door_animations; idx++) {
2004  // door_anim_name
2005  m.door_anim_name.push_back(temp_string);
2006 
2007  // door_anim_coords
2008  m.door_anim_coords.push_back(temp);
2009 
2010  // we want two pairs of coordinates for each animation
2011  m.door_anim_coords.at(idx).push_back(0);
2012  m.door_anim_coords.at(idx).push_back(0);
2013  m.door_anim_coords.at(idx).push_back(0);
2014  m.door_anim_coords.at(idx).push_back(0);
2015 
2016  // door_sounds
2017  m.door_sounds.push_back(temp);
2018 
2019  // door_sound_pan
2020  m.door_sound_pan.push_back(0.0f);
2021  }
2022 }
2023 
2025 {
2027  m.regions.clear();
2028  }
2029 
2030  main_hall_region defaults[] = {
2031  main_hall_region(0, 0, XSTR( "Exit FreeSpace 2", 353), EXIT_REGION, ""),
2032  main_hall_region(1, 'B', XSTR( "Barracks - Manage your FreeSpace 2 pilots", 354), BARRACKS_REGION, ""),
2033  main_hall_region(2, 'R', XSTR( "Ready room - Start or continue a campaign", 355), START_REGION, ""),
2034  main_hall_region(3, 'T', XSTR( "Tech room - View specifications of FreeSpace 2 ships and weaponry", 356), TECH_ROOM_REGION, ""),
2035  main_hall_region(4, 0, XSTR( "Options - Change your FreeSpace 2 options", 357), OPTIONS_REGION, ""),
2036  main_hall_region(5, 'C', XSTR( "Campaign Room - View all available campaigns", 358), CAMPAIGN_ROOM_REGION, ""),
2037  main_hall_region(6, 'G', "Quick start", QUICK_START_REGION, "")
2038  };
2039 
2040  for (int idx = 0; idx < 7; idx++) {
2041  m.regions.push_back(defaults[idx]);
2042  }
2043 
2044  // XSTR( "Multiplayer - Start or join a multiplayer game", 359)
2045  m.default_readyroom = true;
2046 }
2047 
2052 {
2053  // clear the main hall entries
2054  Main_hall_defines.clear();
2055 
2056  // if mainhall.tbl exists, parse it
2057  if (cf_exists_full("mainhall.tbl", CF_TYPE_TABLES)) {
2058  parse_main_hall_table("mainhall.tbl");
2059  }
2060 
2061  // parse any modular tables
2063 }
2064 
2065 // read in main hall table
2067 {
2068  SCP_vector<main_hall_defines> temp_vector;
2070  int idx, s_idx, m_idx;
2071  int num_resolutions = 2;
2072  unsigned int count;
2073  char temp_string[MAX_FILENAME_LEN];
2074  SCP_string temp_scp_string;
2075 
2076  try
2077  {
2078  read_file_text(filename, CF_TYPE_TABLES);
2079 
2080  reset_parse();
2081 
2082  if (optional_string("$Num Resolutions:")) {
2083  stuff_int(&num_resolutions);
2084  }
2085 
2086  if (num_resolutions < 1) {
2087  Error(LOCATION, "$Num Resolutions in %s is %d. (Must be 1 or greater)", filename, num_resolutions);
2088  }
2089 
2090  // go for it
2091  count = Main_hall_defines.size();
2092  while (!optional_string("#end")) {
2093  Main_hall_defines.push_back(temp_vector);
2094  // read in all resolutions
2095  for (m_idx = 0; m_idx < num_resolutions; m_idx++) {
2096  Main_hall_defines.at(count).push_back(temp);
2097  m = &Main_hall_defines.at(count).at(m_idx);
2098 
2099  // ready
2100  required_string("$Main Hall");
2101 
2102  // Parse the entry name for the first resolution, checking for duplicates and erroring if necessary
2103  if (m_idx == 0) {
2104  if (optional_string("+Name:")) {
2105  stuff_string(temp_string, F_RAW, MAX_FILENAME_LEN);
2106 
2107  // we can't have two mainhalls with the same name
2108  if (main_hall_get_pointer(temp_string) == NULL) {
2109  m->name = temp_string;
2110  }
2111  else {
2112  Error(LOCATION, "A mainhall with the name '%s' already exists. All mainhalls must have unique names.", temp_string);
2113  }
2114  }
2115  else {
2116  snprintf(temp_string, MAX_FILENAME_LEN, "%u", count);
2117  m->name = temp_string;
2118  }
2119  }
2120  else {
2121  if (optional_string("+Name:")) {
2122  stuff_string(temp_string, F_RAW, MAX_FILENAME_LEN);
2123 
2129  if (strcmp(temp_string, Main_hall_defines.at(count).at(0).name.c_str()) != 0) {
2130  Error(LOCATION, "The mainhall '%s' has different names for different resolutions. All resolutions must have the same name. Either remove the hi-res entries' names entirely or set them to match the first resolution entry's name.", Main_hall_defines.at(0).at(count).name.c_str());
2131  }
2132  }
2133 
2134  m->name = Main_hall_defines.at(count).at(0).name;
2135  }
2136 
2137  // add cheats
2138  while (optional_string("+Cheat String:")) {
2139  stuff_string(temp_scp_string, F_RAW);
2140  m->cheat.push_back(temp_scp_string);
2141 
2142  if (temp_scp_string.size() > MAIN_HALL_MAX_CHEAT_LEN) {
2143  // Since the value is longer than the cheat buffer it will never match.
2144 
2145  Warning(LOCATION, "The value '%s' for '+Cheat String:' is too long! It can be at most %d characters long.", temp_scp_string.c_str(), MAIN_HALL_MAX_CHEAT_LEN);
2146  }
2147 
2148  required_string("+Anim To Change:");
2149  stuff_string(temp_scp_string, F_NAME);
2150  m->cheat_anim_from.push_back(temp_scp_string);
2151 
2152  required_string("+Anim To Change To:");
2153  stuff_string(temp_scp_string, F_NAME);
2154  m->cheat_anim_to.push_back(temp_scp_string);
2155  }
2156 
2157  // minimum resolution
2158  if (optional_string("+Min Resolution:")) {
2159  stuff_int(&m->min_width);
2160  stuff_int(&m->min_height);
2161  }
2162  else if (m_idx == 0) {
2163  m->min_width = 0;
2164  m->min_height = 0;
2165  }
2166  else {
2169  }
2170 
2171  // minimum aspect ratio
2172  if (optional_string("+Min Aspect Ratio:")) {
2174  }
2175  else {
2176  m->min_aspect_ratio = 0.0f;
2177  }
2178 
2179  // bitmap and mask
2180  required_string("+Bitmap:");
2181  stuff_string(temp_string, F_NAME, MAX_FILENAME_LEN);
2182  m->bitmap = temp_string;
2183 
2184  required_string("+Mask:");
2185  stuff_string(temp_string, F_NAME, MAX_FILENAME_LEN);
2186  m->mask = temp_string;
2187 
2188  required_string("+Music:");
2189  stuff_string(temp_string, F_NAME, MAX_FILENAME_LEN);
2190  m->music_name = temp_string;
2191 
2192  // Goober5000
2193  if (optional_string("+Substitute Music:")) {
2194  stuff_string(temp_string, F_NAME, MAX_FILENAME_LEN);
2195  m->substitute_music_name = temp_string;
2196  }
2197 
2198  if (optional_string("+Help Overlay:")) {
2199  stuff_string(temp_string, F_NAME, MAX_FILENAME_LEN);
2200  m->help_overlay_name = temp_string;
2201  }
2202 
2203  if (optional_string("+Help Overlay Resolution Index:")) {
2205  }
2206  else {
2207  m->help_overlay_resolution_index = m_idx;
2208  }
2209 
2210  // zoom area
2211  if (optional_string("+Zoom To:")) {
2214  }
2215  else {
2216  m->zoom_area_width = -1;
2217  m->zoom_area_height = -1;
2218  }
2219 
2220  // intercom sounds
2221  required_string("+Num Intercom Sounds:");
2223 
2224  // initialise intercom sounds vectors
2226 
2227  for (idx = 0; idx < m->num_random_intercom_sounds; idx++) {
2228  // intercom delay
2229  required_string("+Intercom delay:");
2230  stuff_int(&m->intercom_delay.at(idx).at(0));
2231  stuff_int(&m->intercom_delay.at(idx).at(1));
2232  }
2233 
2234  for (idx = 0; idx < m->num_random_intercom_sounds; idx++) {
2235  // intercom sound id
2236  parse_sound("+Intercom sound:", &m->intercom_sounds.at(idx), "+Intercom sound:", PARSE_SOUND_INTERFACE_SOUND);
2237  }
2238 
2239  for (idx = 0; idx < m->num_random_intercom_sounds; idx++) {
2240  // intercom pan
2241  required_string("+Intercom pan:");
2242  stuff_float(&m->intercom_sound_pan.at(idx));
2243  }
2244 
2245  // misc animations
2246  required_string("+Num Misc Animations:");
2248 
2249  // initialise the misc anim vectors
2250  misc_anim_init(*m);
2251 
2252  for (idx = 0; idx < m->num_misc_animations; idx++) {
2253  // anim names
2254  required_string("+Misc anim:");
2255  stuff_string(temp_string, F_NAME, MAX_FILENAME_LEN);
2256  m->misc_anim_name.at(idx) = (SCP_string)temp_string;
2257  }
2258 
2259  for (idx = 0; idx < m->num_misc_animations; idx++) {
2260  // anim groups, optionally
2261  if (optional_string("+Misc anim group:")) {
2262  stuff_int(&m->misc_anim_group.at(idx));
2263  }
2264  else {
2265  m->misc_anim_group.at(idx) = -1;
2266  }
2267  }
2268 
2269  for (idx = 0; idx < m->num_misc_animations; idx++) {
2270  // anim delay
2271  required_string("+Misc anim delay:");
2272  stuff_int(&m->misc_anim_delay.at(idx).at(0));
2273  stuff_int(&m->misc_anim_delay.at(idx).at(1));
2274  stuff_int(&m->misc_anim_delay.at(idx).at(2));
2275  }
2276 
2277  for (idx = 0; idx < m->num_misc_animations; idx++) {
2278  // anim coords
2279  required_string("+Misc anim coords:");
2280  stuff_int(&m->misc_anim_coords.at(idx).at(0));
2281  stuff_int(&m->misc_anim_coords.at(idx).at(1));
2282  }
2283 
2284  for (idx = 0; idx < m->num_misc_animations; idx++) {
2285  // anim mode
2286  required_string("+Misc anim mode:");
2287  stuff_int(&m->misc_anim_modes.at(idx));
2288  }
2289 
2290  for (idx = 0; idx < m->num_misc_animations; idx++) {
2291  // anim pan
2292  required_string("+Misc anim pan:");
2293  stuff_float(&m->misc_anim_sound_pan.at(idx));
2294  }
2295 
2296  for (idx = 0; idx < m->num_misc_animations; idx++) {
2297  // anim sound id
2298  parse_sound_list("+Misc anim sounds:", m->misc_anim_special_sounds.at(idx), "+Misc anim sounds:", PARSE_SOUND_INTERFACE_SOUND);
2299  }
2300 
2301  for (idx = 0; idx < m->num_misc_animations; idx++) {
2302  // anim sound triggers
2303  required_string("+Misc anim trigger:");
2304  int temp_int = 0;
2305  stuff_int(&temp_int);
2306  for (s_idx = 0; s_idx < temp_int; s_idx++) {
2307  m->misc_anim_special_trigger.at(idx).push_back(0);
2308  stuff_int(&m->misc_anim_special_trigger.at(idx).at(s_idx));
2309  }
2310  }
2311 
2312  for (idx = 0; idx < m->num_misc_animations; idx++) {
2313  // anim sound handles - deprecated, but deal with it just in case
2314  if (optional_string("+Misc anim handles:")) {
2315  advance_to_eoln(NULL);
2316  }
2317  }
2318 
2319  for (idx = 0; idx < m->num_misc_animations; idx++) {
2320  // anim sound flags - table flag deprecated, so ignore user input
2321  if (optional_string("+Misc anim flags:")) {
2322  advance_to_eoln(NULL);
2323  }
2324 
2325  // we need one flag for each sound
2326  Assert(m->misc_anim_special_sounds.at(idx).size() < INT_MAX);
2327  for (s_idx = 0; s_idx < (int)m->misc_anim_special_sounds.at(idx).size(); s_idx++) {
2328  m->misc_anim_sound_flag.at(idx).push_back(0);
2329  }
2330  }
2331 
2332  for (idx = 0; idx < m->num_misc_animations; idx++) {
2333  // render over doors - default to false
2334 
2335  if (optional_string("+Misc anim over doors:")) {
2336  bool temp_b;
2337  stuff_boolean(&temp_b);
2338  m->misc_anim_over_doors.push_back(temp_b);
2339  }
2340  else {
2341  m->misc_anim_over_doors.push_back(0);
2342  }
2343  }
2344 
2345  region_info_init(*m);
2346 
2347  // door animations
2348  required_string("+Num Door Animations:");
2350 
2351  // initialise the door anim vectors
2352  door_anim_init(*m);
2353 
2354  for (idx = 0; idx < m->num_door_animations; idx++) {
2355  // door name
2356  required_string("+Door anim:");
2357  stuff_string(temp_string, F_NAME, MAX_FILENAME_LEN);
2358  m->door_anim_name.at(idx) = (SCP_string)temp_string;
2359  }
2360 
2361  for (idx = 0; idx < m->num_door_animations; idx++) {
2362  // door coords
2363  required_string("+Door coords:");
2364  stuff_int(&m->door_anim_coords.at(idx).at(0));
2365  stuff_int(&m->door_anim_coords.at(idx).at(1));
2366  stuff_int(&m->door_anim_coords.at(idx).at(2));
2367  stuff_int(&m->door_anim_coords.at(idx).at(3));
2368  }
2369 
2370  for (idx = 0; idx < m->num_door_animations; idx++) {
2371  // door open and close sounds
2372  parse_sound_list("+Door sounds:", m->door_sounds.at(idx), "+Door sounds:", (parse_sound_flags)(PARSE_SOUND_INTERFACE_SOUND | PARSE_SOUND_SCP_SOUND_LIST));
2373  }
2374 
2375  for (idx = 0; idx < m->num_door_animations; idx++) {
2376  // door pan value
2377  required_string("+Door pan:");
2378  stuff_float(&m->door_sound_pan[idx]);
2379  }
2380 
2381  int mask;
2382  for (idx = 0; optional_string("+Door mask value:"); idx++) {
2383  // door mask
2384  stuff_string(temp_string, F_RAW, MAX_FILENAME_LEN);
2385 
2386  mask = (int)strtol(temp_string, NULL, 0);
2387  mask = 255 - mask;
2388 
2389  if (idx >= (int)m->regions.size()) {
2390  m->regions.resize(idx + 1);
2391  }
2392  m->regions[idx].mask = mask;
2393  }
2394 
2395  for (idx = 0; optional_string("+Door action:"); idx++) {
2396  // door action
2397 
2398  if (idx >= (int)m->regions.size()) {
2399  m->regions.resize(idx + 1);
2400  }
2401 
2402  if (optional_string("Script")) {
2403  m->regions[idx].action = SCRIPT_REGION;
2404  stuff_string(m->regions[idx].lua_action, F_RAW);
2405  }
2406  else {
2407  stuff_string(temp_scp_string, F_RAW);
2408 
2409  int action = -1;
2410  for (int i = 0; Main_hall_region_map[i].name != NULL; i++) {
2411  if (temp_scp_string == Main_hall_region_map[i].name) {
2412  action = Main_hall_region_map[i].mask;
2413  break;
2414  }
2415  }
2416 
2417  if (action == -1) {
2418  SCP_string err_msg = "";
2419  for (int i = 0; Main_hall_region_map[i].name != NULL; i++) {
2420  if (i != 0) {
2421  err_msg += ", ";
2422  }
2423  err_msg += Main_hall_region_map[i].name;
2424  }
2425 
2426  Error(LOCATION, "Unkown Door Region '%s'! Expected one of: %s", temp_scp_string.c_str(), err_msg.c_str());
2427  }
2428 
2429  m->regions[idx].action = action;
2430  }
2431  }
2432 
2433  for (idx = 0; optional_string("+Door key:"); idx++) {
2434  // door key
2435  stuff_string(temp_string, F_RAW, MAX_FILENAME_LEN);
2436 
2437  if ((int)m->regions.size() <= idx) {
2438  m->regions.resize(idx + 1);
2439  }
2440  m->regions[idx].key = temp_string[0];
2441  }
2442 
2443  for (idx = 0; optional_string("+Door description:"); idx++) {
2444  // region description (tooltip)
2445  stuff_string(temp_scp_string, F_MESSAGE);
2446 
2447  if (temp_scp_string != "default") {
2448  if (idx >= (int)m->regions.size()) {
2449  m->regions.resize(idx + 1);
2450  }
2451 
2452  m->regions[idx].description = temp_scp_string;
2453 
2454  if (idx == 2) {
2455  m->default_readyroom = false;
2456  }
2457  }
2458  }
2459 
2460  // font for tooltips and other text
2461  if (optional_string("+Font:")) {
2462  stuff_int(&m->font);
2463  }
2464  else {
2465  m->font = FONT1;
2466  }
2467 
2468  // tooltip padding
2469  if (optional_string("+Tooltip Padding:")) {
2471  }
2472  else {
2473  m->tooltip_padding = -1; // we'll get the default value later
2474  }
2475 
2476  // tooltip y location
2477  if (optional_string("+Tooltip Y:")) {
2478  stuff_int(&m->region_yval);
2479  }
2480  else {
2481  m->region_yval = -1;
2482  }
2483  }
2484 
2485  count++;
2486  }
2487 
2488  // free up memory from parsing the mainhall tbl
2489  stop_parse();
2490  }
2491  catch (const parse::ParseException& e)
2492  {
2493  mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", filename, e.what()));
2494  return;
2495  }
2496 }
2497 
2502 {
2503  Vasudan_funny = 1;
2504 }
2505 
2511 {
2512  // kind of a hack for now
2513  return (!stricmp(Main_hall->music_name.c_str(), "Psampik") || !stricmp(Main_hall->music_name.c_str(), "Psamtik"));
2514 }
2515 
2520 {
2521  if (Main_hall_paused) {
2522  return;
2523  }
2524 
2525  Main_hall_paused = 1;
2526 
2528 
2530 }
2531 
2536 {
2537  if (!Main_hall_paused) {
2538  return;
2539  }
2540 
2541  Main_hall_paused = 0;
2542 
2544 
2546 }
Definition: sound.cpp:39
#define MISC_ANIM_MODE_TIMED
void bm_unlock(int handle)
Unlocks a bitmap.
Definition: bmpman.cpp:3005
void advance_to_eoln(char *more_terminators)
Definition: parselo.cpp:335
#define MAX_FILENAME_LEN
Definition: pstypes.h:324
int timestamp(int delta_ms)
Definition: timer.cpp:226
int gr_get_current_fontnum()
Definition: font.cpp:545
#define NET_TCP
Definition: psnet2.h:29
int i
Definition: multi_pxo.cpp:466
void mouse_set_pos(int xpos, int ypos)
Definition: mouse.cpp:604
void parse_main_hall_table(const char *filename)
SCP_string music_name
Definition: mainhallmenu.h:57
#define ASF_MENUMUSIC
Definition: audiostr.h:20
int flags
Definition: player.h:104
int Cmdline_freespace_no_music
Definition: cmdline.cpp:271
int Main_hall_inited
int Game_mode
Definition: systemvars.cpp:24
GLfloat GLfloat GLfloat GLfloat h
Definition: Glext.h:7280
int Main_hall_mask
void gr_flip()
Definition: 2d.cpp:2113
char Recent_missions[MAX_RECENT_MISSIONS][MAX_FILENAME_LEN]
Definition: missionload.cpp:34
#define READY_ROOM_REGION
char Game_current_mission_filename[MAX_FILENAME_LEN]
Definition: fredstubs.cpp:26
#define GR_RESIZE_MENU
Definition: 2d.h:684
#define MOUSE_LEFT_BUTTON
Definition: mouse.h:43
main_hall_region_info Main_hall_region_map[]
SCP_vector< int > misc_anim_paused
Definition: mainhallmenu.h:95
GLuint index
Definition: Glext.h:5608
int main_hall_get_overlay_resolution_index()
bitmap * Main_hall_mask_bitmap
int Main_hall_ambient_loop
SCP_vector< SCP_string > cheat_anim_from
Definition: mainhallmenu.h:44
void main_hall_mouse_release_region(int region)
void main_hall_process_help_stuff()
SCP_vector< float > door_sound_pan
Definition: mainhallmenu.h:138
int snazzy_menu_do(ubyte *data, int mask_w, int mask_h, int num_regions, MENU_REGION *regions, int *action, int poll_key, int *key)
Definition: snazzyui.cpp:59
void main_hall_pause()
int gr_get_resolution_class(int width, int height)
Definition: 2d.cpp:773
void _cdecl void void _cdecl void _cdecl Warning(char *filename, int line, SCP_FORMAT_STRING const char *format,...) SCP_FORMAT_STRING_ARGS(3
Assert(pm!=NULL)
#define NETWORK_ERROR_CONNECT_TO_ISP
Definition: psnet2.h:66
#define KEY_1
Definition: key.h:72
int Main_hall_region_linger_stamp
void main_hall_handle_right_clicks()
#define GR_NUM_RESOLUTIONS
Definition: 2d.h:651
#define mprintf(args)
Definition: pstypes.h:238
__inline void gr_string(int x, int y, const char *string, int resize_mode=GR_RESIZE_FULL)
Definition: 2d.h:769
int num_random_intercom_sounds
Definition: mainhallmenu.h:71
ambient sound for the Terran main hall (looping)
Definition: gamesnd.h:299
#define QUICK_START_REGION
int res
Definition: 2d.h:370
int max_h_unscaled
Definition: 2d.h:361
int bm_get_info(int handle, int *w, int *h, ubyte *flags, int *nframes, int *fps)
Gets info on the bitmap indexed by handle.
Definition: bmpman.cpp:769
void main_hall_start_ambient()
int center_h
Definition: 2d.h:363
#define NETWORK_ERROR_NO_PROTOCOL
Definition: psnet2.h:64
GLclampf f
Definition: Glext.h:7097
int Tcp_active
Definition: psnet2.cpp:60
#define ESC_PRESSED
Definition: snazzyui.h:16
int snd_is_playing(int sig)
Definition: sound.cpp:1047
#define Assertion(expr, msg,...)
Definition: clang.h:41
ubyte * Main_hall_mask_data
Definition: 2d.h:82
void player_tips_popup()
#define GR_MAYBE_CLEAR_RES(bmap)
Definition: 2d.h:639
int help_overlay_resolution_index
Definition: mainhallmenu.h:62
int main_hall_get_overlay_id()
#define MULTIPLAYER_REGION
int center_w
Definition: 2d.h:363
void gr_set_screen_scale(int w, int h, int zoom_w, int zoom_h, int max_w, int max_h, int center_w, int center_h, bool force_stretch)
Definition: 2d.cpp:104
char Main_hall_notify_text[300]
void help_overlay_set_state(int overlay_id, int resolution_index, int state)
void gr_set_color_fast(color *dst)
Definition: 2d.cpp:1197
#define EXIT_REGION
std::basic_string< char, std::char_traits< char >, std::allocator< char > > SCP_string
Definition: vmallocator.h:21
int key
parse_sound_flags
Definition: gamesnd.h:36
#define BARRACKS_REGION
void gr_set_bitmap(int bitmap_num, int alphablend_mode, int bitblt_mode, float alpha)
Definition: 2d.cpp:2105
int max_w_unscaled
Definition: 2d.h:361
#define MAIN_HALL_HELP_TIME
int key_to_ascii(int keycode)
Definition: key.cpp:336
int bm_release(int handle, int clear_render_targets)
Frees both a bitmap's data and it's associated slot.
Definition: bmpman.cpp:2603
SCP_vector< SCP_vector< int > > misc_anim_coords
Definition: mainhallmenu.h:101
SCP_vector< int > misc_anim_group
Definition: mainhallmenu.h:98
bool Campaign_room_no_campaigns
Definition: readyroom.cpp:228
SCP_string name
Definition: mainhallmenu.h:41
void snazzy_menu_add_region(MENU_REGION *region, const char *text, int mask, int key, int click_sound)
Definition: snazzyui.cpp:163
int Num_recent_missions
Definition: missionload.cpp:35
script_state Script_system("FS2_Open Scripting")
int Main_hall_frame_skip
char * name
SCP_vector< SCP_vector< main_hall_defines > > Main_hall_defines
#define MISC_ANIM_MODE_LOOP
void misc_anim_init(main_hall_defines &m)
void stuff_float(float *f)
Definition: parselo.cpp:2328
#define BMP_AABITMAP
antialiased bitmap
Definition: bmpman.h:52
void game_increase_skill_level()
Definition: fredstubs.cpp:197
void generic_anim_unload(generic_anim *ga)
Definition: generic.cpp:291
SCP_string Main_hall_cheat
void fishtank_process()
Definition: fishtank.cpp:204
HWND DWORD code
Definition: vddraw.h:425
#define SCRIPT_REGION
int Campaign_file_missing
int mouse_down(int btn)
Definition: mouse.cpp:315
bup bup bup-bup bup bup
Definition: gamesnd.h:348
#define SNAZZY_OVER
Definition: snazzyui.h:28
SCP_vector< SCP_vector< int > > door_sounds
Definition: mainhallmenu.h:135
typedef int(SCP_EXT_CALLCONV *SCPDLL_PFVERSION)(SCPDLL_Version *)
#define gr_reset_clip
Definition: 2d.h:745
#define GENERIC_ANIM_DIRECTION_FORWARDS
Definition: generic.h:11
void parse_sound(const char *tag, int *idx_dest, const char *object_name, parse_sound_flags flags)
Definition: gamesnd.cpp:445
SCP_string substitute_music_name
Definition: mainhallmenu.h:58
int Main_hall_bitmap_h
void main_hall_table_init()
color Color_bright
Definition: alphacolors.cpp:28
color Color_bright_green
Definition: alphacolors.cpp:31
#define nprintf(args)
Definition: pstypes.h:239
#define GM_MULTIPLAYER
Definition: systemvars.h:18
SCP_string bitmap
Definition: mainhallmenu.h:53
void snazzy_menu_close()
Definition: snazzyui.cpp:276
void main_hall_notify_do()
#define NETWORK_ERROR_LAN_AND_RAS
Definition: psnet2.h:67
int Main_hall_last_clicked_region
main_hall_defines * main_hall_get_pointer(const SCP_string &name_to_find)
int cf_exists_full(const char *filename, int dir_type)
Definition: cfile.cpp:527
void region_info_init(main_hall_defines &m)
#define NETWORK_ERROR_NONE
Definition: psnet2.h:61
void _cdecl gr_printf_menu_zoomed(int x, int y, const char *format,...)
Definition: font.cpp:328
char * filename
void main_hall_render_misc_anims(float frametime, bool over_doors)
void main_hall_do_multi_ready()
void stuff_string(char *outstr, int type, int len, char *terminators)
Definition: parselo.cpp:1189
SCP_vector< int > misc_anim_modes
Definition: mainhallmenu.h:104
void movie_play_two(char *name1, char *name2)
Definition: movie.cpp:159
SCP_vector< SCP_string > cheat
Definition: mainhallmenu.h:43
void generic_anim_render(generic_anim *ga, float frametime, int x, int y, bool menu)
Definition: generic.cpp:437
#define w(p)
Definition: modelsinc.h:68
#define CF_TYPE_TABLES
Definition: cfile.h:50
sprintf(buf,"(%f,%f,%f)", v3->xyz.x, v3->xyz.y, v3->xyz.z)
int main_hall_id()
const float RAND_MAX_1f
Definition: pstypes.h:309
void gr_shade(int x, int y, int w, int h, int resize_mode)
Definition: 2d.cpp:2085
SCP_vector< SCP_string > cheat_anim_to
Definition: mainhallmenu.h:45
#define KEY_ENTER
Definition: key.h:125
#define WSAEADDRINUSE
Definition: config.h:137
void get_version_string()
Definition: fredstubs.cpp:194
void main_hall_stop_ambient()
void main_hall_set_notify_string(const char *str)
#define TECH_ROOM_REGION
int required_string(const char *pstr)
Definition: parselo.cpp:468
#define NETWORK_ERROR_NO_WINSOCK
Definition: psnet2.h:63
SCP_vector< int > Main_hall_door_sound_handles
int snd_play(game_snd *gs, float pan, float vol_scale, int priority, bool is_voice_msg)
Definition: sound.cpp:517
Definition: bmpman.h:101
int psnet_get_network_status()
Definition: psnet2.cpp:670
void main_hall_cull_door_sounds()
void main_hall_render_door_anims(float frametime)
#define CONNECTION_SPEED_NONE
Definition: multi.h:709
int Multi_connection_speed
Definition: multi.cpp:113
void main_hall_reset_ambient_vol()
int optional_string(const char *pstr)
Definition: parselo.cpp:539
bitmap * bm_lock(int handle, ubyte bpp, ubyte flags, bool nodebug)
Locks down the bitmap indexed by bitmapnum.
Definition: bmpman.cpp:1754
int Main_hall_notify_stamp
int Recording
SCP_vector< bool > misc_anim_over_doors
Definition: mainhallmenu.h:119
#define GR_1024_THRESHOLD_WIDTH
Definition: 2d.h:655
BM_TYPE
Definition: bmpman.h:71
int Game_ships_tbl_valid
Definition: fredstubs.cpp:181
void snazzy_menu_init()
Definition: snazzyui.cpp:34
void read_file_text(const char *filename, int mode, char *processed_text, char *raw_text)
Definition: parselo.cpp:1995
#define NUM_MAIN_HALL_MAX_REGIONS
int psnet_use_protocol(int protocol)
Definition: psnet2.cpp:596
#define MH2_OVERLAY
Definition: contexthelp.h:31
void main_hall_blit_version()
int idx
Definition: multiui.cpp:761
#define SKILL_LEVEL_REGION
door in main hall closes
Definition: gamesnd.h:311
void main_hall_get_name(SCP_string &name, unsigned int index)
void audiostream_unpause(int i, bool via_sexp_or_script)
Definition: audiostr.cpp:1960
#define LOAD_MISSION_REGION
int Main_hall_intercom_sound_handle
shader Main_hall_tooltip_shader
int Main_hall_music_handle
int main_hall_is_vasudan()
SCP_vector< game_snd > Snds_iface
Definition: gamesnd.cpp:20
unsigned char ubyte
Definition: pstypes.h:62
SCP_vector< generic_anim > Main_hall_misc_anim
door in main hall opens
Definition: gamesnd.h:310
const char * XSTR(const char *str, int index)
Definition: localize.cpp:851
#define MAIN_HALL_NOTIFY_TIME
int mission_load_up_campaign(player *pl)
color Color_bright_red
Definition: alphacolors.cpp:34
void main_hall_blit_table_status()
void main_hall_handle_random_intercom_sounds()
SCP_string mask
Definition: mainhallmenu.h:54
void stuff_boolean(int *i, bool a_to_eol)
Definition: parselo.cpp:2519
int max_w
Definition: 2d.h:360
#define F_MESSAGE
Definition: parselo.h:42
SCP_vector< float > misc_anim_sound_pan
Definition: mainhallmenu.h:107
void main_hall_maybe_blit_tooltips()
int Vasudan_funny_plate
void _cdecl void void _cdecl Error(const char *filename, int line, SCP_FORMAT_STRING const char *format,...) SCP_FORMAT_STRING_ARGS(3
Parse the list of sounds SCP style (just indexes and/or files names, no count first) ...
Definition: gamesnd.h:40
int Main_hall_right_click
void main_hall_handle_region_anims()
GLbitfield flags
Definition: Glext.h:6722
menu_music Spooled_music[MAX_SPOOLED_MUSIC]
Definition: eventmusic.cpp:249
int Vasudan_funny
void reset_parse(char *text)
Definition: parselo.cpp:3305
void main_hall_handle_mouse_location(int cur_region)
GLuint const GLchar * name
Definition: Glext.h:5608
__inline void gr_line(int x1, int y1, int x2, int y2, int resize_mode=GR_RESIZE_FULL)
Definition: 2d.h:791
int main_hall_get_resolution_index(int main_hall_num)
int max_w_unscaled_zoomed
Definition: 2d.h:362
void main_hall_exit_game()
int current_mission
int Main_hall_next_intercom_sound
int bm_load(const char *real_filename)
Loads a bitmap so we can draw with it later.
Definition: bmpman.cpp:1119
void stuff_int(int *i)
Definition: parselo.cpp:2372
void audiostream_close_file(int i, int fade)
Definition: audiostr.cpp:1772
bool gr_resize_screen_pos(int *x, int *y, int *w, int *h, int resize_mode)
Definition: 2d.cpp:212
int Main_hall_bitmap_w
#define GENERIC_ANIM_DIRECTION_NOLOOP
Definition: generic.h:13
void door_anim_init(main_hall_defines &m)
SCP_vector< int > intercom_sounds
Definition: mainhallmenu.h:77
#define MOUSE_RIGHT_BUTTON
Definition: mouse.h:44
typedef float(SCP_EXT_CALLCONV *SCPTRACKIR_PFFLOATVOID)()
color Color_bright_white
Definition: alphacolors.cpp:32
void main_hall_do(float frametime)
int Main_hall_bitmap
#define FONT1
Definition: font.h:65
SCP_vector< SCP_vector< int > > misc_anim_special_trigger
Definition: mainhallmenu.h:113
campaign Campaign
#define GR_1024_THRESHOLD_HEIGHT
Definition: 2d.h:656
#define MH_OVERLAY
Definition: contexthelp.h:24
void fishtank_stop()
Definition: fishtank.cpp:176
float frand()
Return random value in range 0.0..1.0- (1.0- means the closest number less than 1.0)
Definition: floating.cpp:35
void main_hall_unpause()
int Main_hall_help_stamp
void stop_parse()
Definition: parselo.cpp:2071
SCP_vector< main_hall_region > regions
Definition: mainhallmenu.h:146
player * Player
screen gr_screen
Definition: 2d.cpp:46
void gr_get_string_size(int *w, int *h, const char *text, int len=9999)
Definition: font.cpp:196
#define START_REGION
void generic_anim_init(generic_anim *ga)
Definition: generic.cpp:80
SCP_vector< SCP_vector< int > > intercom_delay
Definition: mainhallmenu.h:74
Search for sound in the interface part of sounds.tbl.
Definition: gamesnd.h:39
int snd_play_looping(game_snd *gs, float pan, int start_loop, int stop_loop, float vol_scale, int scriptingUpdateVolume)
Definition: sound.cpp:822
int Main_hall_mouse_region
void mission_campaign_jump_to_mission(char *name, bool no_skip)
void main_hall_vasudan_funny()
#define MAIN_HALL_REGION_LINGER
#define F_NAME
Definition: parselo.h:34
void snd_set_volume(int sig, float volume)
Definition: sound.cpp:920
#define LOCATION
Definition: pstypes.h:245
float Master_event_music_volume
Definition: eventmusic.cpp:40
int max_h
Definition: 2d.h:360
void gr_reset_screen_scale()
Definition: 2d.cpp:176
void snd_set_pos(int snd_handle, game_snd *gs, float val, int as_pct)
Definition: sound.cpp:1180
void main_hall_start_music()
int Main_hall_mask_h
#define OPTIONS_REGION
const char * Skill_level_names(int skill_level, int translate=1)
Definition: aicode.cpp:208
#define timestamp_elapsed(stamp)
Definition: timer.h:102
#define SNAZZY_CLICKED
Definition: snazzyui.h:29
ptr_u data
Pointer to data, or maybe offset into VRAM.
Definition: bmpman.h:109
void intercom_sounds_init(main_hall_defines &m)
BM_TYPE bm_get_type(int handle)
Returns the image type of the given bitmap handle.
Definition: bmpman.cpp:894
void audiostream_play(int i, float volume, int looping)
Definition: audiostr.cpp:1803
int Game_skill_level
Definition: fredstubs.cpp:170
mouse click
Definition: gamesnd.h:287
const GLfloat * m
Definition: Glext.h:10319
bool EvalString(const char *string, const char *format=NULL, void *rtn=NULL, const char *debug_str=NULL)
Definition: scripting.cpp:1083
bool movie_play(char *name)
Definition: movie.cpp:72
#define NETWORK_ERROR_NO_TYPE
Definition: psnet2.h:62
void main_hall_close()
GLint GLsizei count
Definition: Gl.h:1491
int parse_modular_table(const char *name_check, void(*parse_callback)(const char *filename), int path_type, int sort_type)
Definition: parselo.cpp:4205
void gr_bitmap(int _x, int _y, int resize_mode)
Definition: 2d.cpp:1303
void main_hall_campaign_cheat()
SCP_vector< float > intercom_sound_pan
Definition: mainhallmenu.h:80
int event_music_get_spooled_music_index(const char *name)
int temp
Definition: lua.cpp:4996
int audiostream_open(const char *filename, int type)
Definition: audiostr.cpp:1713
void gr_create_shader(shader *shade, ubyte r, ubyte g, ubyte b, ubyte c)
Definition: 2d.cpp:1211
#define MAIN_HALL_MAX_CHEAT_LEN
#define PLAYER_FLAGS_IS_MULTI
Definition: player.h:42
int Tcp_failure_code
Definition: psnet2.cpp:63
void audiostream_pause(int i, bool via_sexp_or_script)
Definition: audiostr.cpp:1943
#define GM_NORMAL
Definition: systemvars.h:19
void snd_stop(int sig)
Definition: sound.cpp:875
SCP_vector< SCP_vector< int > > door_anim_coords
Definition: mainhallmenu.h:132
void gamesnd_play_iface(int n)
Definition: gamesnd.cpp:260
int Om_tracker_flag
SCP_vector< SCP_vector< int > > misc_anim_sound_flag
Definition: mainhallmenu.h:116
void gr_set_font(int fontnum)
Definition: font.cpp:566
void parse_sound_list(const char *tag, SCP_vector< int > &destination, const char *object_name, parse_sound_flags flags)
Definition: gamesnd.cpp:468
void main_hall_stop_music(bool fade)
int main_hall_get_index(const SCP_string &name_to_find)
void gr_set_shader(shader *shade)
Definition: 2d.cpp:1220
SCP_vector< SCP_vector< int > > misc_anim_delay
Definition: mainhallmenu.h:92
#define KEY_2
Definition: key.h:73
int help_overlay_get_index(const char *overlay_name)
int generic_anim_stream(generic_anim *ga)
Definition: generic.cpp:159
SCP_vector< generic_anim > Main_hall_door_anim
int Cmdline_reparse_mainhall
Definition: cmdline.cpp:510
void gameseq_post_event(int event)
GLenum GLint GLuint mask
Definition: Glext.h:5605
void main_hall_mouse_grab_region(int region)
void main_hall_init(const SCP_string &main_hall_name)
int main_hall_get_music_index(int main_hall_num)
SCP_vector< SCP_string > misc_anim_name
Definition: mainhallmenu.h:89
#define stricmp(s1, s2)
Definition: config.h:271
multi_global_options Multi_options_g
void help_overlay_maybe_blit(int overlay_id, int resolution_index)
int help_overlay_active(int overlay_id)
SCP_vector< SCP_string > door_anim_name
Definition: mainhallmenu.h:128
int max_h_unscaled_zoomed
Definition: 2d.h:362
SCP_vector< SCP_vector< int > > misc_anim_special_sounds
Definition: mainhallmenu.h:110
#define KEY_F3
Definition: key.h:145
cmission missions[MAX_CAMPAIGN_MISSIONS]
#define GENERIC_ANIM_DIRECTION_BACKWARDS
Definition: generic.h:12
void game_process_cheats(int k)
#define CAMPAIGN_ROOM_REGION
int Main_hall_mask_w
int Main_hall_next_intercom_sound_stamp
#define F_RAW
Definition: parselo.h:44
MENU_REGION Main_hall_region[NUM_MAIN_HALL_MAX_REGIONS]
#define strcpy_s(...)
Definition: safe_strings.h:67
void mission_campaign_load_failure_popup()
SCP_string help_overlay_name
Definition: mainhallmenu.h:61
#define KEY_3
Definition: key.h:74
char filename[MAX_FILENAME_LEN]
Definition: eventmusic.h:66
int Main_hall_overlay_id
#define GR_RESIZE_MENU_ZOOMED
Definition: 2d.h:685
#define SMF_VALID
Definition: eventmusic.h:72
int Game_weapons_tbl_valid
Definition: fredstubs.cpp:180
#define MISC_ANIM_MODE_HOLD