Author Topic: Modular Mainhall.tbl  (Read 29323 times)

0 Members and 1 Guest are viewing this topic.

Offline Iss Mneur

  • 210
  • TODO:
Please setup/change bm_load to accept a const char* (or even a reference to a SCP_string) just so that the casting is done in one place not in every caller.

Code: [Select]
+ nprintf(("General","WARNING!, Could not load misc %s anim in main hall\n",Main_hall->misc_anim_name.at(idx)));
Assuming misc_anim_name is a SCP_string, you need to call c_str() because gcc will not like you otherwise (this is because var arg functions must only be passed PODs. Visual studio is helpful and does it implicitly).


Please do the same for generic_anim_init() as bm_load().

You should Assert before every cast of a size_t to an int (MAX_INT).


Otherwise, looks good, I will test it later.
"I love deadlines. I like the whooshing sound they make as they fly by." -Douglas Adams
wxLauncher 0.9.4 public beta (now with no config file editing for FRED) | wxLauncher 2.0 Request for Comments

 

Offline CommanderDJ

  • Software engineer
  • 210
    • Minecraft
You should Assert before every cast of a size_t to an int (MAX_INT).

To clarify, what exactly am I Asserting? That the size_t is less than MAX_INT?
[16:57] <CommanderDJ> What prompted the decision to split WiH into acts?
[16:58] <battuta> it was long, we wanted to release something
[16:58] <battuta> it felt good to have a target to hit
[17:00] <RangerKarl> not sure if talking about strike mission, or jerking off
[17:00] <CommanderDJ> WUT
[17:00] <CommanderDJ> hahahahaha
[17:00] <battuta> hahahaha
[17:00] <RangerKarl> same thing really, if you think about it

 

Offline The E

  • He's Ebeneezer Goode
  • Moderator
  • 213
  • Nothing personal, just tech support.
    • Steam
    • Twitter
Nope. You do an assertion on the variable you are going to cast to ensure it is >= 0, because size_t is an unsigned type.
If I'm just aching this can't go on
I came from chasing dreams to feel alone
There must be changes, miss to feel strong
I really need lifе to touch me
--Evergrey, Where August Mourns

 

Offline CommanderDJ

  • Software engineer
  • 210
    • Minecraft
I don't understand. I'm casting from a size_t to an int, so won't the resulting int always be positive anyway since size_t is unsigned?
[16:57] <CommanderDJ> What prompted the decision to split WiH into acts?
[16:58] <battuta> it was long, we wanted to release something
[16:58] <battuta> it felt good to have a target to hit
[17:00] <RangerKarl> not sure if talking about strike mission, or jerking off
[17:00] <CommanderDJ> WUT
[17:00] <CommanderDJ> hahahahaha
[17:00] <battuta> hahahaha
[17:00] <RangerKarl> same thing really, if you think about it

 

Offline Iss Mneur

  • 210
  • TODO:
I don't understand. I'm casting from a size_t to an int, so won't the resulting int always be positive anyway since size_t is unsigned?
Yes, The E misunderstood and got it backwards.

The Assertion should check that the result of the size() (which returns a size_t) call is less than MAX_INT becuase otherwise the int could overflow and be negative.  Admittedly having enough memory to cause this problem is rather rare, but it is hard to say when memory corruption could be caught by it.
"I love deadlines. I like the whooshing sound they make as they fly by." -Douglas Adams
wxLauncher 0.9.4 public beta (now with no config file editing for FRED) | wxLauncher 2.0 Request for Comments

 

Offline CommanderDJ

  • Software engineer
  • 210
    • Minecraft
Ah, okay, that makes sense. Here's the patch with the issues addressed:

Code: [Select]
Index: code/bmpman/bmpman.cpp
===================================================================
--- code/bmpman/bmpman.cpp (revision 8114)
+++ code/bmpman/bmpman.cpp (working copy)
@@ -605,6 +605,14 @@
 }
 
 /**
+ * Same as bm_load above, just with an SCP_string
+ */
+int bm_load(SCP_string& filename)
+{
+ return bm_load(const_cast<char*> (filename.c_str()));
+}
+
+/**
  * Special load function. Basically allows you to load a bitmap which already exists (by filename).
  *
  * This is useful because in some cases we need to have a bitmap which is locked in screen format
Index: code/bmpman/bmpman.h
===================================================================
--- code/bmpman/bmpman.h (revision 8114)
+++ code/bmpman/bmpman.h (working copy)
@@ -89,6 +89,7 @@
 // the bitmap.   On success, it returns the bitmap
 // number.
 int bm_load(char * filename);
+int bm_load(SCP_string& filename);
 
 // special load function. basically allows you to load a bitmap which already exists (by filename).
 // this is useful because in some cases we need to have a bitmap which is locked in screen format
Index: code/graphics/generic.cpp
===================================================================
--- code/graphics/generic.cpp (revision 8114)
+++ code/graphics/generic.cpp (working copy)
@@ -100,6 +100,13 @@
  ga->width = 0;
  ga->bitmap_id = -1;
 }
+/**
+ * CommanderDJ - same as generic_anim_init, just with an SCP_string
+ */
+void generic_anim_init(generic_anim *ga, SCP_string& filename)
+{
+ generic_anim_init(ga, const_cast<char*> (filename.c_str()));
+}
 
 // Goober5000
 void generic_bitmap_init(generic_bitmap *gb, char *filename)
Index: code/graphics/generic.h
===================================================================
--- code/graphics/generic.h (revision 8114)
+++ code/graphics/generic.h (working copy)
@@ -54,6 +54,7 @@
 
 int generic_anim_init_and_stream(generic_anim *anim, char *anim_filename, ubyte bg_type, bool attempt_hi_res);
 void generic_anim_init(generic_anim *ga, char *filename = NULL);
+void generic_anim_init(generic_anim *ga, SCP_string& filename);
 void generic_bitmap_init(generic_bitmap *gb, char *filename = NULL);
 int generic_anim_load(generic_anim *ga);
 int generic_anim_stream(generic_anim *ga);
Index: code/menuui/mainhallmenu.cpp
===================================================================
--- code/menuui/mainhallmenu.cpp (revision 8114)
+++ code/menuui/mainhallmenu.cpp (working copy)
@@ -59,12 +59,12 @@
 #define NUM_REGIONS 7 // (6 + 1 for multiplayer equivalent of campaign room)
 typedef struct main_hall_defines {
  // bitmap and mask
- char bitmap[MAX_FILENAME_LEN];
- char mask[MAX_FILENAME_LEN];
+ SCP_string bitmap;
+ SCP_string mask;
 
  // music
- char music_name[MAX_FILENAME_LEN];
- char substitute_music_name[MAX_FILENAME_LEN];
+ SCP_string music_name;
+ SCP_string substitute_music_name;
 
  // intercom defines -------------------
 
@@ -87,7 +87,7 @@
  int num_misc_animations;
 
  // filenames of the misc animations
- char misc_anim_name[MAX_MISC_ANIMATIONS][MAX_FILENAME_LEN];
+ SCP_vector<SCP_string> misc_anim_name;
 
  // Time until we will next play a given misc animation, min delay, and max delay
  SCP_vector<SCP_vector<int> > misc_anim_delay;
@@ -110,39 +110,36 @@
  //sounds for each of the misc anims
  SCP_vector<SCP_vector<int> > misc_anim_special_sounds;
 
- // [N][0] == # of triggers, [N][1-9] >= frame num
- int misc_anim_special_trigger[MAX_MISC_ANIMATIONS][10];
+ //frame number triggers for each of the misc anims
+ SCP_vector<SCP_vector<int> > misc_anim_special_trigger;
 
- // [N][0] == # of handles, [N][1-9] == sound handle num
- int misc_anim_sound_handles[MAX_MISC_ANIMATIONS][10];
+ //flags for each of the misc anim sounds
+ SCP_vector<SCP_vector<int> > misc_anim_sound_flag;
 
- // [N][0] == # of handles, [N][1-9] == sound "should" be playing
- int misc_anim_sound_flag[MAX_MISC_ANIMATIONS][10];
 
-
  // door animations --------------------
 
  // # of door animations
  int num_door_animations;
 
  // filenames of the door animations
- char door_anim_name[MAX_DOOR_ANIMATIONS][MAX_FILENAME_LEN];
+ SCP_vector<SCP_string> door_anim_name;
 
  // first pair : coords of where to play a given door anim
  // second pair : center of a given door anim in windowed mode
- int door_anim_coords[MAX_DOOR_ANIMATIONS][4];
+ SCP_vector<SCP_vector<int> > door_anim_coords;
 
  // sounds for each region (open/close)
  SCP_vector<SCP_vector<int> > door_sounds;
 
  // pan values for the door sounds
- float door_sound_pan[MAX_DOOR_ANIMATIONS];
+ SCP_vector<float> door_sound_pan;
 
 
  // region descriptions ----------------
 
  // text (tooltip) description
- char *region_descript[NUM_REGIONS];
+ SCP_vector<char*> region_descript;
 
  // y coord of where to draw tooltip text
  int region_yval;
@@ -503,7 +500,7 @@
  return;
  }
 
- int idx,s_idx;
+ int idx;
  char temp[100], whee[100];
 
  //reparse the table here if the relevant cmdline flag is set
@@ -529,13 +526,13 @@
  Main_hall = &Main_hall_defines[gr_screen.res][main_hall_num];
 
  // tooltip strings
- Main_hall->region_descript[0] = XSTR( "Exit FreeSpace 2", 353);
- Main_hall->region_descript[1] = XSTR( "Barracks - Manage your FreeSpace 2 pilots", 354);
- Main_hall->region_descript[2] = XSTR( "Ready room - Start or continue a campaign", 355);
- Main_hall->region_descript[3] = XSTR( "Tech room - View specifications of FreeSpace 2 ships and weaponry", 356);
- Main_hall->region_descript[4] = XSTR( "Options - Change your FreeSpace 2 options", 357);
- Main_hall->region_descript[5] = XSTR( "Campaign Room - View all available campaigns", 358);
- Main_hall->region_descript[6] = XSTR( "Multiplayer - Start or join a multiplayer game", 359);
+ Main_hall->region_descript.at(0) = XSTR( "Exit FreeSpace 2", 353);
+ Main_hall->region_descript.at(1) = XSTR( "Barracks - Manage your FreeSpace 2 pilots", 354);
+ Main_hall->region_descript.at(2) = XSTR( "Ready room - Start or continue a campaign", 355);
+ Main_hall->region_descript.at(3) = XSTR( "Tech room - View specifications of FreeSpace 2 ships and weaponry", 356);
+ Main_hall->region_descript.at(4) = XSTR( "Options - Change your FreeSpace 2 options", 357);
+ Main_hall->region_descript.at(5) = XSTR( "Campaign Room - View all available campaigns", 358);
+ Main_hall->region_descript.at(6) = XSTR( "Multiplayer - Start or join a multiplayer game", 359);
 
  // init tooltip shader // nearly black
  gr_create_shader(&Main_hall_tooltip_shader, 5, 5, 5, 168);
@@ -543,7 +540,7 @@
  // load the background bitmap
  Main_hall_bitmap = bm_load(Main_hall->bitmap);
  if (Main_hall_bitmap < 0) {
- nprintf(("General","WARNING! Couldn't load main hall background bitmap %s\n", Main_hall->bitmap));
+ nprintf(("General","WARNING! Couldn't load main hall background bitmap %s\n", Main_hall->bitmap.c_str()));
  }
  bg_type = bm_get_type(Main_hall_bitmap);
 
@@ -558,7 +555,7 @@
  // load the mask
  Main_hall_mask = bm_load(Main_hall->mask);
  if (Main_hall_mask < 0) {
- nprintf(("General","WARNING! Couldn't load main hall background mask %s\n", Main_hall->mask));
+ nprintf(("General","WARNING! Couldn't load main hall background mask %s\n", Main_hall->mask.c_str()));
  if (gr_screen.res == 0) {
  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);
  } else {
@@ -573,10 +570,10 @@
 
  // load up the misc animations, and nullify all the delay timestamps for the misc animations
  for (idx=0;idx<Main_hall->num_misc_animations;idx++) {
- generic_anim_init(&Main_hall_misc_anim[idx], Main_hall->misc_anim_name[idx]);
+ generic_anim_init(&Main_hall_misc_anim[idx], const_cast<char*>(Main_hall->misc_anim_name.at(idx).c_str()));
  Main_hall_misc_anim[idx].ani.bg_type = bg_type;
  if (generic_anim_stream(&Main_hall_misc_anim[idx]) == -1) {
- nprintf(("General","WARNING!, Could not load misc %s anim in main hall\n",Main_hall->misc_anim_name[idx]));
+ nprintf(("General","WARNING!, Could not load misc %s anim in main hall\n",Main_hall->misc_anim_name.at(idx).c_str()));
  } else {
  //start paused
  if (Main_hall->misc_anim_modes.at(idx) == MISC_ANIM_MODE_HOLD)
@@ -592,10 +589,10 @@
 
  // load up the door animations
  for (idx=0;idx<Main_hall->num_door_animations;idx++) {
- generic_anim_init(&Main_hall_door_anim[idx], Main_hall->door_anim_name[idx]);
+ generic_anim_init(&Main_hall_door_anim[idx], const_cast<char*>(Main_hall->door_anim_name.at(idx).c_str()));
  Main_hall_door_anim[idx].ani.bg_type = bg_type;
  if (generic_anim_stream(&Main_hall_door_anim[idx]) == -1) {
- nprintf(("General","WARNING!, Could not load door anim %s in main hall\n",Main_hall->door_anim_name[idx]));
+ nprintf(("General","WARNING!, Could not load door anim %s in main hall\n",Main_hall->door_anim_name.at(idx).c_str()));
  } else {
  Main_hall_door_anim[idx].direction = GENERIC_ANIM_DIRECTION_BACKWARDS | GENERIC_ANIM_DIRECTION_NOLOOP;
  }
@@ -639,14 +636,6 @@
  Main_hall_door_sound_handles[idx] = -1;
  }
 
- // zero out the misc anim sounds
- for (idx=0;idx<Main_hall->num_misc_animations;idx++) {
- for (s_idx = 1;s_idx < 10;s_idx++) {
- Main_hall->misc_anim_sound_handles[idx][s_idx] = -1;
- Main_hall->misc_anim_sound_flag[idx][s_idx] = 0;
- }
- }
-
  // skip the first frame
  Main_hall_frame_skip = 1;
 
@@ -1009,10 +998,13 @@
 
  // stop any playing misc animation sounds
  for (idx=0;idx<Main_hall->num_misc_animations;idx++) {
- for (s_idx=1;s_idx<10;s_idx++) {
- if (snd_is_playing(Main_hall->misc_anim_sound_handles[idx][s_idx])) {
- snd_stop(Main_hall->misc_anim_sound_handles[idx][s_idx]);
- Main_hall->misc_anim_sound_handles[idx][s_idx] = -1;
+
+ //if this goes wrong, the int cast could overflow
+ Assert(Main_hall->misc_anim_special_sounds.at(idx).size() < INT_MAX);
+
+ for (s_idx=0;s_idx<(int)Main_hall->misc_anim_special_sounds.at(idx).size();s_idx++) {
+ if (snd_is_playing(Main_hall->misc_anim_special_sounds.at(idx).at(s_idx))) {
+ snd_stop(Main_hall->misc_anim_special_sounds.at(idx).at(s_idx));
  }
  }
  }
@@ -1048,13 +1040,13 @@
  hall = &Main_hall_defines[gr_screen.res][main_hall_num];
 
  // Goober5000 - try substitute first
- index = event_music_get_spooled_music_index(hall->substitute_music_name);
+ index = event_music_get_spooled_music_index(const_cast<char*>(hall->substitute_music_name.c_str()));
  if ((index >= 0) && (Spooled_music[index].flags & SMF_VALID)) {
  return index;
  }
 
  // now try regular
- index = event_music_get_spooled_music_index(hall->music_name);
+ index = event_music_get_spooled_music_index(const_cast<char*>(hall->music_name.c_str()));
  if ((index >= 0) && (Spooled_music[index].flags & SMF_VALID)) {
  return index;
  }
@@ -1175,28 +1167,30 @@
  // kill the timestamp
  Main_hall->misc_anim_delay.at(idx).at(0) = -1;
 
+
  // reset the "should be playing" flags
- for (s_idx=1;s_idx<10;s_idx++) {
- Main_hall->misc_anim_sound_flag[idx][s_idx] = 0;
+ Assert(Main_hall->misc_anim_sound_flag.at(idx).size() < INT_MAX);
+ for (s_idx=0;s_idx<(int)Main_hall->misc_anim_sound_flag.at(idx).size();s_idx++) {
+ Main_hall->misc_anim_sound_flag.at(idx).at(s_idx) = 0;
  }
  }
  }
  // animation is not paused
  else {
- for (s_idx = 0; (unsigned)s_idx < Main_hall->misc_anim_special_sounds.at(idx).size(); s_idx++) {
+ Assert(Main_hall->misc_anim_special_sounds.at(idx).size() < INT_MAX);
+ for (s_idx = 0; s_idx < (int)Main_hall->misc_anim_special_sounds.at(idx).size(); s_idx++) {
  // if we've passed the trigger point, then play the sound and break out of the loop
- if ((Main_hall_misc_anim[idx].current_frame >= Main_hall->misc_anim_special_trigger[idx][s_idx+1]) && !Main_hall->misc_anim_sound_flag[idx][s_idx+1]) {
- Main_hall->misc_anim_sound_flag[idx][s_idx+1] = 1;
+ if ((Main_hall_misc_anim[idx].current_frame >= Main_hall->misc_anim_special_trigger.at(idx).at(s_idx)) && !Main_hall->misc_anim_sound_flag.at(idx).at(s_idx)) {
+ Main_hall->misc_anim_sound_flag.at(idx).at(s_idx) = 1;
 
  // if the sound is already playing, then kill it. This is a pretty safe thing to do since we can assume that
  // by the time we get to this point again, the sound will have been long finished
- if (snd_is_playing(Main_hall->misc_anim_sound_handles[idx][s_idx+1])) {
- snd_stop(Main_hall->misc_anim_sound_handles[idx][s_idx+1]);
- Main_hall->misc_anim_sound_handles[idx][s_idx+1] = -1;
+ if (snd_is_playing(Main_hall->misc_anim_special_sounds.at(idx).at(s_idx))) {
+ snd_stop(Main_hall->misc_anim_special_sounds.at(idx).at(s_idx));
  }
 
  // play the sound
- Main_hall->misc_anim_sound_handles[idx][s_idx+1] = snd_play(&Snds_iface[Main_hall->misc_anim_special_sounds.at(idx).at(s_idx)],Main_hall->misc_anim_sound_pan.at(idx));
+ snd_play(&Snds_iface[Main_hall->misc_anim_special_sounds.at(idx).at(s_idx)],Main_hall->misc_anim_sound_pan.at(idx));
  break;
  }
  }
@@ -1214,8 +1208,9 @@
  //don't reset sound for MISC_ANIM_MODE_HOLD
  if (Main_hall->misc_anim_modes.at(idx) != MISC_ANIM_MODE_HOLD) {
  // reset the "should be playing" flags
- for (s_idx=1;s_idx<10;s_idx++) {
- Main_hall->misc_anim_sound_flag[idx][s_idx] = 0;
+ Assert(Main_hall->misc_anim_sound_flag.at(idx).size() < INT_MAX);
+ for (s_idx=0;s_idx<(int)Main_hall->misc_anim_sound_flag.at(idx).size();s_idx++) {
+ Main_hall->misc_anim_sound_flag.at(idx).at(s_idx) = 0;
  }
  }
  }
@@ -1240,7 +1235,7 @@
  if (Main_hall_door_anim[idx].num_frames > 0) {
  // first pair : coords of where to play a given door anim
  // second pair : center of a given door anim in windowed mode
- generic_anim_render(&Main_hall_door_anim[idx], frametime, Main_hall->door_anim_coords[idx][0], Main_hall->door_anim_coords[idx][1]);
+ generic_anim_render(&Main_hall_door_anim[idx], frametime, Main_hall->door_anim_coords.at(idx).at(0), Main_hall->door_anim_coords.at(idx).at(1));
  }
  }
 }
@@ -1309,7 +1304,7 @@
  if (Main_hall_door_sound_handles[region] != -1) {
  snd_stop(Main_hall_door_sound_handles[region]);
  }
- Main_hall_door_sound_handles[region] = snd_play(&Snds_iface[Main_hall->door_sounds.at(region).at(1)], Main_hall->door_sound_pan[region]);
+ Main_hall_door_sound_handles[region] = snd_play(&Snds_iface[Main_hall->door_sounds.at(region).at(1)], Main_hall->door_sound_pan.at(region));
 
  //TODO: track current frame
  snd_set_pos(Main_hall_door_sound_handles[region], &Snds_iface[SND_MAIN_HALL_DOOR_CLOSE],
@@ -1338,7 +1333,7 @@
  if (Main_hall_door_sound_handles[region] != -1) {
  snd_stop(Main_hall_door_sound_handles[region]);
  }
- Main_hall_door_sound_handles[region] = snd_play(&Snds_iface[Main_hall->door_sounds.at(region).at(0)],Main_hall->door_sound_pan[region]);
+ Main_hall_door_sound_handles[region] = snd_play(&Snds_iface[Main_hall->door_sounds.at(region).at(0)],Main_hall->door_sound_pan.at(region));
 
  // start the sound playing at the right spot relative to the completion of the animation
  if ( (Main_hall_door_anim[region].num_frames > 0) && (Main_hall_door_anim[region].current_frame != -1) ) {
@@ -1366,8 +1361,8 @@
  }
 
  // set the position of the mouse cursor and the newly clicked region
- int mx = Main_hall->door_anim_coords[new_region][2];
- int my = Main_hall->door_anim_coords[new_region][3];
+ int mx = Main_hall->door_anim_coords.at(new_region).at(2);
+ int my = Main_hall->door_anim_coords.at(new_region).at(3);
  gr_resize_screen_pos( &mx, &my );
  mouse_set_pos( mx, my );
 
@@ -1551,13 +1546,13 @@
  if (!help_overlay_active(Main_hall_overlay_id)) {
  int shader_y = (Main_hall->region_yval) - Main_hall_tooltip_padding[gr_screen.res]; // subtract more to pull higher
  // get the width of the string
- gr_get_string_size(&w, NULL, Main_hall->region_descript[text_index]);
+ gr_get_string_size(&w, NULL, Main_hall->region_descript.at(text_index));
 
  gr_set_shader(&Main_hall_tooltip_shader);
  gr_shade(0, shader_y, gr_screen.clip_width_unscaled, (gr_screen.clip_height_unscaled - shader_y));
 
  gr_set_color_fast(&Color_bright_white);
- gr_string((gr_screen.max_w_unscaled - w)/2, Main_hall->region_yval, Main_hall->region_descript[text_index]);
+ gr_string((gr_screen.max_w_unscaled - w)/2, Main_hall->region_yval, Main_hall->region_descript.at(text_index));
  }
 }
 
@@ -1607,12 +1602,8 @@
 //To be called after num_intercom_sounds has been parsed
 void intercom_sounds_init(main_hall_defines &m)
 {
- if (!m.intercom_delay.empty()) {
- //if one of these isn't empty, none of these should be empty
- Assert(!m.intercom_sounds.empty());
- Assert(!m.intercom_sound_pan.empty());
-
- //since we could be reparsing with a different number of intercom sounds, clear these and reinitialise
+ if (Cmdline_reparse_mainhall) {
+ //we could be reparsing with a different number of intercom sounds, so clear these and reinitialise
  m.intercom_delay.clear();
  m.intercom_sounds.clear();
  m.intercom_sound_pan.clear();
@@ -1636,28 +1627,32 @@
  }
 }
 
+//helper function for initialising misc anim vectors based on number of anims
+//to be called after num_misc_animations has been parsed
 void misc_anim_init(main_hall_defines &m)
 {
- if (!m.misc_anim_delay.empty()) {
- //if one of these isn't empty, none of these should be
- Assert(!m.misc_anim_paused.empty());
- Assert(!m.misc_anim_group.empty());
- Assert(!m.misc_anim_coords.empty());
- Assert(!m.misc_anim_modes.empty());
- Assert(!m.misc_anim_sound_pan.empty());
-
- //since we could be reparsing with a different number of misc anims, clear these and reinitialise
+ if (Cmdline_reparse_mainhall) {
+ //we could be reparsing with a different number of misc anims, so clear these and reinitialise
+ m.misc_anim_name.clear();
  m.misc_anim_delay.clear();
  m.misc_anim_paused.clear();
  m.misc_anim_group.clear();
  m.misc_anim_coords.clear();
  m.misc_anim_modes.clear();
  m.misc_anim_sound_pan.clear();
+ m.misc_anim_special_sounds.clear();
+ m.misc_anim_special_trigger.clear();
+ m.misc_anim_sound_flag.clear();
  }
 
  SCP_vector<int> temp;
+ SCP_string temp_string;
 
  for (int idx=0; idx<m.num_misc_animations; idx++) {
+
+ //misc_anim_name
+ m.misc_anim_name.push_back(temp_string);
+
  //misc_anim_delay
  m.misc_anim_delay.push_back(temp);
 
@@ -1682,15 +1677,71 @@
  m.misc_anim_modes.push_back(MISC_ANIM_MODE_LOOP);
 
  //misc_anim_sound_pan
- m.misc_anim_sound_pan.push_back(0);
+ m.misc_anim_sound_pan.push_back(0.0f);
+
+ //misc_anim_special_sounds
+ m.misc_anim_special_sounds.push_back(temp); //parse_sound_list deals with the rest of the initialisation for this one
+
+ //misc_anim_special_trigger
+ m.misc_anim_special_trigger.push_back(temp);
+
+ m.misc_anim_special_trigger.at(idx).push_back(0);
+
+ //misc_anim_sound_flag
+ m.misc_anim_sound_flag.push_back(temp);
  }
 }
 
+//helper function for initialising door anim vectors based on number of anims
+//to be called after num_door_animations has been parsed
+void door_anim_init(main_hall_defines &m)
+{
+ if (Cmdline_reparse_mainhall) {
+ //since we could be reparsing with a different number of door anims, clear these and reinitialise
+ m.door_anim_name.clear();
+ m.door_anim_coords.clear();
+ m.door_sounds.clear();
+ m.door_sound_pan.clear();
+ m.region_descript.clear();
+ }
+
+ SCP_vector<int> temp;
+ SCP_string temp_string;
+
+ for(int idx=0; idx<m.num_door_animations; idx++)
+ {
+ //door_anim_name
+ m.door_anim_name.push_back(temp_string);
+
+ //door_anim_coords
+ m.door_anim_coords.push_back(temp);
+
+ //we want two pairs of coordinates for each animation
+ m.door_anim_coords.at(idx).push_back(0);
+ m.door_anim_coords.at(idx).push_back(0);
+ m.door_anim_coords.at(idx).push_back(0);
+ m.door_anim_coords.at(idx).push_back(0);
+
+ //door_sounds
+ m.door_sounds.push_back(temp);
+
+ //door_sound_pan
+ m.door_sound_pan.push_back(0.0f);
+ }
+
+ //region_descript
+ for (int idx=0; idx<NUM_REGIONS; idx++) {
+ m.region_descript.push_back(NULL);
+ }
+
+}
+
 // read in main hall table
 void main_hall_read_table()
 {
  main_hall_defines *m, temp;
  int count, idx, s_idx, m_idx, rval;
+ char temp_string[MAX_FILENAME_LEN];
 
  if ((rval = setjmp(parse_abort)) != 0) {
  mprintf(("TABLES: Unable to parse '%s'!  Error code = %i.\n", "mainhall.tbl", rval));
@@ -1706,7 +1757,7 @@
  while (!optional_string("#end")) {
  // read in 2 resolutions
  for (m_idx=0; m_idx<GR_NUM_RESOLUTIONS; m_idx++) {
- // maybe use a temp main hall stuct
+ // maybe use a temp main hall struct
  if (count >= MAIN_HALLS_MAX) {
  m = &temp;
  Warning(LOCATION, "Number of main halls in mainhall.tbl has exceeded max of %d. All further main halls will be ignored.", MAIN_HALLS_MAX);
@@ -1721,17 +1772,21 @@
 
  // bitmap and mask
  required_string("+Bitmap:");
- stuff_string(m->bitmap, F_NAME, MAX_FILENAME_LEN);
+ stuff_string(temp_string, F_NAME, MAX_FILENAME_LEN);
+ m->bitmap = temp_string;
 
  required_string("+Mask:");
- stuff_string(m->mask, F_NAME, MAX_FILENAME_LEN);
+ stuff_string(temp_string, F_NAME, MAX_FILENAME_LEN);
+ m->mask = temp_string;
 
  required_string("+Music:");
- stuff_string(m->music_name, F_NAME, MAX_FILENAME_LEN);
+ stuff_string(temp_string, F_NAME, MAX_FILENAME_LEN);
+ m->music_name = temp_string;
 
  // Goober5000
  if (optional_string("+Substitute Music:")) {
- stuff_string(m->substitute_music_name, F_NAME, MAX_FILENAME_LEN);
+ stuff_string(temp_string, F_NAME, MAX_FILENAME_LEN);
+ m->substitute_music_name = temp_string;
  }
 
  // intercom sounds
@@ -1778,7 +1833,8 @@
  for (idx=0; idx<m->num_misc_animations; idx++) {
  // anim names
  required_string("+Misc anim:");
- stuff_string(m->misc_anim_name[idx], F_NAME, MAX_FILENAME_LEN);
+ stuff_string(temp_string, F_NAME, MAX_FILENAME_LEN);
+ m->misc_anim_name.at(idx) = (SCP_string)temp_string;
  }
 
  for (idx=0; idx<m->num_misc_animations; idx++) {
@@ -1819,30 +1875,39 @@
 
  for (idx=0; idx<m->num_misc_animations; idx++) {
  // anim sound id
- SCP_vector<int> temp; //this is a short term hack and will be properly fixed when main_hall_defines is vectorised
- m->misc_anim_special_sounds.push_back(temp);
  parse_sound_list("+Misc anim sounds:", m->misc_anim_special_sounds.at(idx), "+Misc anim sounds:", PARSE_SOUND_INTERFACE_SOUND);
  }
 
  for (idx=0; idx<m->num_misc_animations; idx++) {
  // anim sound triggers
  required_string("+Misc anim trigger:");
- stuff_int(&m->misc_anim_special_trigger[idx][0]);
- for (s_idx=0; s_idx<m->misc_anim_special_trigger[idx][0]; s_idx++) {
- stuff_int(&m->misc_anim_special_trigger[idx][s_idx + 1]);
+ int temp = 0;
+ stuff_int(&temp);
+ for (s_idx=0; s_idx<temp; s_idx++) {
+ m->misc_anim_special_trigger.at(idx).push_back(0);
+ stuff_int(&m->misc_anim_special_trigger.at(idx).at(s_idx));
  }
  }
 
  for (idx=0; idx<m->num_misc_animations; idx++) {
- // anim sound handles
- required_string("+Misc anim handles:");
- stuff_int(&m->misc_anim_sound_handles[idx][0]);
+ // anim sound handles - deprecated, but deal with it just in case
+ if(optional_string("+Misc anim handles:")) {
+ advance_to_eoln(NULL);
+ }
+
  }
 
  for (idx=0; idx<m->num_misc_animations; idx++) {
- // anim sound flags
- required_string("+Misc anim flags:");
- stuff_int(&m->misc_anim_sound_flag[idx][0]);
+ // anim sound flags - table flag deprecated, so ignore user input
+ if(optional_string("+Misc anim flags:")) {
+ advance_to_eoln(NULL);
+ }
+
+ //we need one flag for each sound
+ Assert(m->misc_anim_special_sounds.at(idx).size() < INT_MAX);
+ for(s_idx=0; s_idx<(int)m->misc_anim_special_sounds.at(idx).size(); s_idx++) {
+ m->misc_anim_sound_flag.at(idx).push_back(0);
+ }
  }
 
  // door animations
@@ -1853,25 +1918,27 @@
  m->num_door_animations = MAX_DOOR_ANIMATIONS;
  }
 
+ //initialise the door anim vectors
+ door_anim_init(*m);
+
  for (idx=0; idx<m->num_door_animations; idx++) {
  // door name
  required_string("+Door anim:");
- stuff_string(m->door_anim_name[idx], F_NAME, MAX_FILENAME_LEN);
+ stuff_string(temp_string, F_NAME, MAX_FILENAME_LEN);
+ m->door_anim_name.at(idx) = (SCP_string)temp_string;
  }
 
  for (idx=0; idx<m->num_door_animations; idx++) {
  // door coords
  required_string("+Door coords:");
- stuff_int(&m->door_anim_coords[idx][0]);
- stuff_int(&m->door_anim_coords[idx][1]);
- stuff_int(&m->door_anim_coords[idx][2]);
- stuff_int(&m->door_anim_coords[idx][3]);
+ stuff_int(&m->door_anim_coords.at(idx).at(0));
+ stuff_int(&m->door_anim_coords.at(idx).at(1));
+ stuff_int(&m->door_anim_coords.at(idx).at(2));
+ stuff_int(&m->door_anim_coords.at(idx).at(3));
  }
 
  for (idx=0; idx<m->num_door_animations; idx++) {
  // door open and close sounds
- SCP_vector<int> temp; //this is a short term hack and will be properly fixed when main_hall_defines is vectorised
- m->door_sounds.push_back(temp);
  parse_sound_list("+Door sounds:", m->door_sounds.at(idx), "+Door sounds:", (parse_sound_flags)(PARSE_SOUND_INTERFACE_SOUND | PARSE_SOUND_SCP_SOUND_LIST));
  }
 
@@ -1884,9 +1951,6 @@
  // tooltip y location
  required_string("+Tooltip Y:");
  stuff_int(&m->region_yval);
- for (idx=0; idx<NUM_REGIONS; idx++) {
- m->region_descript[idx] = NULL;
- }
  }
 
  if (count < MAIN_HALLS_MAX) {
@@ -1906,11 +1970,11 @@
  Main_hall_defines[GR_1024][hall].door_sounds.at(OPTIONS_REGION).at(1) = SND_VASUDAN_BUP;
 
  // set head anim. hehe
- strcpy_s(Main_hall_defines[GR_1024][hall].door_anim_name[OPTIONS_REGION], "2_vhallheads");
+ Main_hall_defines[GR_1024][hall].door_anim_name.at(OPTIONS_REGION) = "2_vhallheads";
 
  // set the background
- strcpy_s(Main_hall_defines[GR_640][hall].bitmap, "vhallhead");
- strcpy_s(Main_hall_defines[GR_1024][hall].bitmap, "2_vhallhead");
+ Main_hall_defines[GR_640][hall].bitmap = "vhallhead";
+ Main_hall_defines[GR_1024][hall].bitmap = "2_vhallhead";
  }
 
  // free up memory from parsing the mainhall tbl
@@ -1926,7 +1990,7 @@
 int main_hall_is_vasudan()
 {
  // kind of a hack for now
- return (!stricmp(Main_hall->music_name, "Psampik") || !stricmp(Main_hall->music_name, "Psamtik"));
+ return (!stricmp(Main_hall->music_name.c_str(), "Psampik") || !stricmp(Main_hall->music_name.c_str(), "Psamtik"));
 }
 
 // silence sounds on mainhall if we hit a pause mode (ie. lost window focus, minimized, etc);

As usual, apply straight to an updated trunk. I'm getting no issues, but of course someone else will need to verify that. :D
[16:57] <CommanderDJ> What prompted the decision to split WiH into acts?
[16:58] <battuta> it was long, we wanted to release something
[16:58] <battuta> it felt good to have a target to hit
[17:00] <RangerKarl> not sure if talking about strike mission, or jerking off
[17:00] <CommanderDJ> WUT
[17:00] <CommanderDJ> hahahahaha
[17:00] <battuta> hahahaha
[17:00] <RangerKarl> same thing really, if you think about it

 

Offline Iss Mneur

  • 210
  • TODO:
committed as 8117.
"I love deadlines. I like the whooshing sound they make as they fly by." -Douglas Adams
wxLauncher 0.9.4 public beta (now with no config file editing for FRED) | wxLauncher 2.0 Request for Comments

 

Offline CommanderDJ

  • Software engineer
  • 210
    • Minecraft
Hello everyone!
A slightly rushed update as I need to leave for work in about two minutes, but here's a patch which makes the maximum number of intercom sounds, misc anims and door anims dynamic (ie removes the limit completely).

This will need a fair bit of testing; I haven't tested it as thoroughly as I would like, but will do so over the next day or two. One thing in particular: this patch affects how misc anim groups are handled a bit by the code, so these must be tested to make sure they function as they did previously. Retail mainhalls don't use misc anim groups, which means that you'll need to test this particular aspect of the patch by downloading MjnMixael's Beta Mainhall Pack available here. The rest can be tested with just the retail mainhalls. Testers: please pay attention to detail and make sure things function as they should (sounds are playing, animations are playing, sounds and anims are in sync etc). Try coming back to the mainhall after a mission or a trip to the tech room, and please test both with and without the -reparse_mainhall flag. As usual, anything wonky can be reported here.

Code: [Select]
Index: code/menuui/mainhallmenu.cpp
===================================================================
--- code/menuui/mainhallmenu.cpp (revision 8127)
+++ code/menuui/mainhallmenu.cpp (working copy)
@@ -48,9 +48,9 @@
 // ----------------------------------------------------------------------------
 // MAIN HALL DATA DEFINES
 //
-#define MAX_RANDOM_INTERCOM_SOUNDS 10
-#define MAX_MISC_ANIMATIONS 32
-#define MAX_DOOR_ANIMATIONS 10
+//#define MAX_RANDOM_INTERCOM_SOUNDS 10 CommanderDJ - these are dynamic now
+//#define MAX_MISC_ANIMATIONS 32
+//#define MAX_DOOR_ANIMATIONS 10
 
 #define MISC_ANIM_MODE_LOOP 0 // loop the animation
 #define MISC_ANIM_MODE_HOLD 1 // play to the end and hold the animation
@@ -221,7 +221,7 @@
 //
 
 // the misc animations themselves
-generic_anim Main_hall_misc_anim[MAX_MISC_ANIMATIONS];
+SCP_vector<generic_anim> Main_hall_misc_anim;
 
 // handle starting, stopping and randomizing misc animations
 void main_hall_handle_misc_anims();
@@ -240,12 +240,8 @@
 #define DOOR_TEXT_Y 450
 
 // the door animations themselves
-//anim *Main_hall_door_anim[MAX_DOOR_ANIMATIONS];
-generic_anim Main_hall_door_anim[MAX_DOOR_ANIMATIONS];
+SCP_vector<generic_anim> Main_hall_door_anim;
 
-// the instance of a given door animation
-//anim_instance *Main_hall_door_anim_instance[MAX_DOOR_ANIMATIONS];
-
 // render all playing door animations
 void main_hall_render_door_anims(float frametime);
 
@@ -303,9 +299,7 @@
 #define ALLENDER_REGION 4
 
 // handles to the sound instances of the doors opening/closing
-int Main_hall_door_sound_handles[MAX_DOOR_ANIMATIONS] = {
- -1,-1,-1,-1,-1,-1
-};
+SCP_vector<int> Main_hall_door_sound_handles;
 
 // sound handle for looping ambient sound
 int Main_hall_ambient_loop = -1;
@@ -567,17 +561,22 @@
  Main_hall_mask_data = (ubyte*)Main_hall_mask_bitmap->data;
  bm_get_info(Main_hall_mask, &Main_hall_mask_w, &Main_hall_mask_h);
  }
+
+ //In case we're re-entering the mainhall
+ Main_hall_misc_anim.clear();
 
  // load up the misc animations, and nullify all the delay timestamps for the misc animations
  for (idx=0;idx<Main_hall->num_misc_animations;idx++) {
- generic_anim_init(&Main_hall_misc_anim[idx], Main_hall->misc_anim_name.at(idx).c_str());
- Main_hall_misc_anim[idx].ani.bg_type = bg_type;
- if (generic_anim_stream(&Main_hall_misc_anim[idx]) == -1) {
+ generic_anim temp;
+ generic_anim_init(&temp, Main_hall->misc_anim_name.at(idx).c_str());
+ Main_hall_misc_anim.push_back(temp);
+ Main_hall_misc_anim.at(idx).ani.bg_type = bg_type;
+ if (generic_anim_stream(&Main_hall_misc_anim.at(idx)) == -1) {
  nprintf(("General","WARNING!, Could not load misc %s anim in main hall\n",Main_hall->misc_anim_name.at(idx).c_str()));
  } else {
  //start paused
  if (Main_hall->misc_anim_modes.at(idx) == MISC_ANIM_MODE_HOLD)
- Main_hall_misc_anim[idx].direction |= GENERIC_ANIM_DIRECTION_NOLOOP;
+ Main_hall_misc_anim.at(idx).direction |= GENERIC_ANIM_DIRECTION_NOLOOP;
  }
 
  // null out the delay timestamps
@@ -587,14 +586,19 @@
  Main_hall->misc_anim_paused.at(idx) = true;
  }
 
+ //In case we're re-entering the mainhall
+ Main_hall_door_anim.clear();
+
  // load up the door animations
  for (idx=0;idx<Main_hall->num_door_animations;idx++) {
- generic_anim_init(&Main_hall_door_anim[idx], Main_hall->door_anim_name.at(idx));
- Main_hall_door_anim[idx].ani.bg_type = bg_type;
- if (generic_anim_stream(&Main_hall_door_anim[idx]) == -1) {
+ generic_anim temp;
+ generic_anim_init(&temp, Main_hall->door_anim_name.at(idx));
+ Main_hall_door_anim.push_back(temp);
+ Main_hall_door_anim.at(idx).ani.bg_type = bg_type;
+ if (generic_anim_stream(&Main_hall_door_anim.at(idx)) == -1) {
  nprintf(("General","WARNING!, Could not load door anim %s in main hall\n",Main_hall->door_anim_name.at(idx).c_str()));
  } else {
- Main_hall_door_anim[idx].direction = GENERIC_ANIM_DIRECTION_BACKWARDS | GENERIC_ANIM_DIRECTION_NOLOOP;
+ Main_hall_door_anim.at(idx).direction = GENERIC_ANIM_DIRECTION_BACKWARDS | GENERIC_ANIM_DIRECTION_NOLOOP;
  }
  }
 
@@ -631,9 +635,10 @@
 
  strcpy_s(Main_hall_campaign_cheat, "");
 
- // zero out the door sounds
+ // initialise door sound handles
+ Main_hall_door_sound_handles.clear();
  for (idx=0;idx<Main_hall->num_door_animations;idx++) {
- Main_hall_door_sound_handles[idx] = -1;
+ Main_hall_door_sound_handles.push_back(-1);
  }
 
  // skip the first frame
@@ -976,23 +981,23 @@
 
  // free up any (possibly) playing misc animation handles
  for (idx=0;idx<Main_hall->num_misc_animations;idx++) {
- if (Main_hall_misc_anim[idx].num_frames > 0) {
- generic_anim_unload(&Main_hall_misc_anim[idx]);
+ if (Main_hall_misc_anim.at(idx).num_frames > 0) {
+ generic_anim_unload(&Main_hall_misc_anim.at(idx));
  }
  }
 
  // free up any (possibly) playing door animation handles
  for (idx=0;idx<Main_hall->num_door_animations;idx++) {
- if (Main_hall_door_anim[idx].num_frames > 0) {
- generic_anim_unload(&Main_hall_door_anim[idx]);
+ if (Main_hall_door_anim.at(idx).num_frames > 0) {
+ generic_anim_unload(&Main_hall_door_anim.at(idx));
  }
  }
 
  // stop any playing door sounds
  for (idx=0;idx<Main_hall->num_door_animations-2;idx++) { // don't cut off the glow sounds (requested by Dan)
- if ( (Main_hall_door_sound_handles[idx] != -1) && snd_is_playing(Main_hall_door_sound_handles[idx]) ) {
- snd_stop(Main_hall_door_sound_handles[idx]);
- Main_hall_door_sound_handles[idx] = -1;
+ if ( (Main_hall_door_sound_handles.at(idx) != -1) && snd_is_playing(Main_hall_door_sound_handles.at(idx)) ) {
+ snd_stop(Main_hall_door_sound_handles.at(idx));
+ Main_hall_door_sound_handles.at(idx) = -1;
  }
  }
 
@@ -1105,14 +1110,16 @@
 // render all playing misc animations
 void main_hall_render_misc_anims(float frametime)
 {
- int idx, s_idx;
- Assert(MAX_MISC_ANIMATIONS <= 32); // otherwise the bitfield trick won't work and we'll need to use an array of booleans
- int jdx, group_anims_weve_checked = 0;
+ int idx, s_idx, jdx;
+ SCP_vector<bool> group_anims_weve_checked;
 
  // render all misc animations
  for (idx = 0; idx < Main_hall->num_misc_animations; idx++) {
+ //give it a spot in the vector
+ group_anims_weve_checked.push_back(false);
+
  // render it
- if (Main_hall_misc_anim[idx].num_frames > 0) {
+ if (Main_hall_misc_anim.at(idx).num_frames > 0) {
  // animation is paused
  if (Main_hall->misc_anim_paused.at(idx)) {
  // if the timestamp is -1, then regenerate it
@@ -1121,19 +1128,25 @@
 
  // if this is part of a group, we should do additional checking
  if (Main_hall->misc_anim_group.at(idx) >= 0) {
+
  // make sure we haven't already checked it
- if (!(group_anims_weve_checked & (1<<idx))) {
- int group_indexes[MAX_MISC_ANIMATIONS];
- int num_group_indexes = 0;
+ if (group_anims_weve_checked.at(idx) == false) {
+ SCP_vector<int> group_indexes; //stores indexes of which anims are part of a group
  bool all_neg1 = true;
 
  // okay... now we need to make sure all anims in this group are paused and -1
  for (jdx = 0; jdx < Main_hall->num_misc_animations; jdx++) {
  if (Main_hall->misc_anim_group.at(jdx) == Main_hall->misc_anim_group.at(idx)) {
- group_anims_weve_checked |= (1<<jdx);
- group_indexes[num_group_indexes] = jdx;
- num_group_indexes++;
+ Assert(group_anims_weve_checked.size() < INT_MAX);
+ if((int)group_anims_weve_checked.size() <= jdx) {
+ group_anims_weve_checked.push_back(true);
+ }
+ else {
+ group_anims_weve_checked.at(jdx) = true;
+ }
 
+ group_indexes.push_back(jdx);
+
  if (!Main_hall->misc_anim_paused.at(jdx) || Main_hall->misc_anim_delay.at(jdx).at(0) != -1) {
  all_neg1 = false;
  }
@@ -1142,7 +1155,8 @@
 
  // if the entire group is paused and off, pick a random one to regenerate
  if (all_neg1) {
- regen_idx = group_indexes[rand() % num_group_indexes];
+ Assert(group_indexes.size() < INT_MAX);
+ regen_idx = group_indexes[rand() % (int)group_indexes.size()];
  }
  }
  }
@@ -1161,8 +1175,8 @@
  // if the timestamp is not -1 and has popped, play the anim and make the timestamp -1
  } else if (timestamp_elapsed(Main_hall->misc_anim_delay.at(idx).at(0))) {
  Main_hall->misc_anim_paused.at(idx) = false;
- Main_hall_misc_anim[idx].current_frame = 0;
- Main_hall_misc_anim[idx].anim_time = 0.0;
+ Main_hall_misc_anim.at(idx).current_frame = 0;
+ Main_hall_misc_anim.at(idx).anim_time = 0.0;
 
  // kill the timestamp
  Main_hall->misc_anim_delay.at(idx).at(0) = -1;
@@ -1180,7 +1194,7 @@
  Assert(Main_hall->misc_anim_special_sounds.at(idx).size() < INT_MAX);
  for (s_idx = 0; s_idx < (int)Main_hall->misc_anim_special_sounds.at(idx).size(); s_idx++) {
  // if we've passed the trigger point, then play the sound and break out of the loop
- if ((Main_hall_misc_anim[idx].current_frame >= Main_hall->misc_anim_special_trigger.at(idx).at(s_idx)) && !Main_hall->misc_anim_sound_flag.at(idx).at(s_idx)) {
+ if ((Main_hall_misc_anim.at(idx).current_frame >= Main_hall->misc_anim_special_trigger.at(idx).at(s_idx)) && !Main_hall->misc_anim_sound_flag.at(idx).at(s_idx)) {
  Main_hall->misc_anim_sound_flag.at(idx).at(s_idx) = 1;
 
  // if the sound is already playing, then kill it. This is a pretty safe thing to do since we can assume that
@@ -1196,7 +1210,7 @@
  }
 
  // animation has reached the last frame
- if (Main_hall_misc_anim[idx].current_frame == Main_hall_misc_anim[idx].num_frames - 1) {
+ if (Main_hall_misc_anim.at(idx).current_frame == Main_hall_misc_anim.at(idx).num_frames - 1) {
  Main_hall->misc_anim_delay.at(idx).at(0) = -1;
 
  //this helps the above code reset the timers
@@ -1219,7 +1233,7 @@
  if (Main_hall_frame_skip || Main_hall_paused) {
  frametime = 0;
  }
- generic_anim_render(&Main_hall_misc_anim[idx], frametime, Main_hall->misc_anim_coords.at(idx).at(0), Main_hall->misc_anim_coords.at(idx).at(1));
+ 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));
  }
  }
  }
@@ -1231,11 +1245,12 @@
  int idx;
 
  // render all door animations
- for (idx=0;idx<MAX_DOOR_ANIMATIONS;idx++) {
- if (Main_hall_door_anim[idx].num_frames > 0) {
+ Assert(Main_hall_door_anim.size() < INT_MAX);
+ for (idx=0;idx<(int)Main_hall_door_anim.size();idx++) {
+ if (Main_hall_door_anim.at(idx).num_frames > 0) {
  // first pair : coords of where to play a given door anim
  // second pair : center of a given door anim in windowed mode
- generic_anim_render(&Main_hall_door_anim[idx], frametime, Main_hall->door_anim_coords.at(idx).at(0), Main_hall->door_anim_coords.at(idx).at(1));
+ 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));
  }
  }
 }
@@ -1296,21 +1311,21 @@
  }
 
  //run backwards and stop at the first frame
- Main_hall_door_anim[region].direction = GENERIC_ANIM_DIRECTION_BACKWARDS | GENERIC_ANIM_DIRECTION_NOLOOP;
+ Main_hall_door_anim.at(region).direction = GENERIC_ANIM_DIRECTION_BACKWARDS | GENERIC_ANIM_DIRECTION_NOLOOP;
 
  // check for door sounds, ignoring the OPTIONS_REGION (which isn't a door)
- if ((Main_hall_door_anim[region].num_frames > 0)) {
+ if ((Main_hall_door_anim.at(region).num_frames > 0)) {
  // don't stop the toaster oven or microwave regions from playing all the way through
- if (Main_hall_door_sound_handles[region] != -1) {
- snd_stop(Main_hall_door_sound_handles[region]);
+ if (Main_hall_door_sound_handles.at(region) != -1) {
+ snd_stop(Main_hall_door_sound_handles.at(region));
  }
- Main_hall_door_sound_handles[region] = snd_play(&Snds_iface[Main_hall->door_sounds.at(region).at(1)], Main_hall->door_sound_pan.at(region));
+ Main_hall_door_sound_handles.at(region) = snd_play(&Snds_iface[Main_hall->door_sounds.at(region).at(1)], Main_hall->door_sound_pan.at(region));
 
  //TODO: track current frame
- snd_set_pos(Main_hall_door_sound_handles[region], &Snds_iface[SND_MAIN_HALL_DOOR_CLOSE],
- (float)((Main_hall_door_anim[region].keyframe) ? Main_hall_door_anim[region].keyframe :
- Main_hall_door_anim[region].num_frames - Main_hall_door_anim[region].current_frame) /
- (float)Main_hall_door_anim[region].num_frames, 1);
+ snd_set_pos(Main_hall_door_sound_handles.at(region), &Snds_iface[SND_MAIN_HALL_DOOR_CLOSE],
+ (float)((Main_hall_door_anim.at(region).keyframe) ? Main_hall_door_anim.at(region).keyframe :
+ Main_hall_door_anim.at(region).num_frames - Main_hall_door_anim.at(region).current_frame) /
+ (float)Main_hall_door_anim.at(region).num_frames, 1);
  }
 }
 
@@ -1322,23 +1337,23 @@
  }
 
  //run forwards
- Main_hall_door_anim[region].direction = GENERIC_ANIM_DIRECTION_FORWARDS;
+ Main_hall_door_anim.at(region).direction = GENERIC_ANIM_DIRECTION_FORWARDS;
  //stay on last frame if we have no keyframe
- if (!Main_hall_door_anim[region].keyframe) {
- Main_hall_door_anim[region].direction += GENERIC_ANIM_DIRECTION_NOLOOP;
+ if (!Main_hall_door_anim.at(region).keyframe) {
+ Main_hall_door_anim.at(region).direction += GENERIC_ANIM_DIRECTION_NOLOOP;
  }
 
  // check for opening/starting sounds
  // kill the currently playing sounds if necessary
- if (Main_hall_door_sound_handles[region] != -1) {
- snd_stop(Main_hall_door_sound_handles[region]);
+ if (Main_hall_door_sound_handles.at(region) != -1) {
+ snd_stop(Main_hall_door_sound_handles.at(region));
  }
- Main_hall_door_sound_handles[region] = snd_play(&Snds_iface[Main_hall->door_sounds.at(region).at(0)],Main_hall->door_sound_pan.at(region));
+ Main_hall_door_sound_handles.at(region) = snd_play(&Snds_iface[Main_hall->door_sounds.at(region).at(0)],Main_hall->door_sound_pan.at(region));
 
  // start the sound playing at the right spot relative to the completion of the animation
- if ( (Main_hall_door_anim[region].num_frames > 0) && (Main_hall_door_anim[region].current_frame != -1) ) {
- snd_set_pos(Main_hall_door_sound_handles[region],&Snds_iface[SND_MAIN_HALL_DOOR_OPEN],
- (float)Main_hall_door_anim[region].current_frame / (float)Main_hall_door_anim[region].num_frames,1);
+ if ( (Main_hall_door_anim.at(region).num_frames > 0) && (Main_hall_door_anim.at(region).current_frame != -1) ) {
+ snd_set_pos(Main_hall_door_sound_handles.at(region),&Snds_iface[SND_MAIN_HALL_DOOR_OPEN],
+ (float)Main_hall_door_anim.at(region).current_frame / (float)Main_hall_door_anim.at(region).num_frames,1);
  }
 }
 
@@ -1384,9 +1399,10 @@
 {
  int idx;
  // 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
- for (idx=0;idx<Main_hall->num_door_animations;idx++) {
- if ( (Main_hall_door_sound_handles[idx] != -1) && !snd_is_playing(Main_hall_door_sound_handles[idx]) ) {
- Main_hall_door_sound_handles[idx] = -1;
+ Assert(Main_hall_door_sound_handles.size() < INT_MAX);
+ for (idx=0;idx<(int)Main_hall_door_sound_handles.size();idx++) {
+ if ( (Main_hall_door_sound_handles.at(idx) != -1) && !snd_is_playing(Main_hall_door_sound_handles.at(idx)) ) {
+ Main_hall_door_sound_handles.at(idx) = -1;
  }
  }
 }
@@ -1795,11 +1811,6 @@
  required_string("+Num Intercom Sounds:");
  stuff_int(&m->num_random_intercom_sounds);
 
- if (m->num_random_intercom_sounds > MAX_RANDOM_INTERCOM_SOUNDS) {
- Warning(LOCATION, "Num Intercom Sounds exceeds maximum!");
- m->num_random_intercom_sounds = MAX_RANDOM_INTERCOM_SOUNDS;
- }
-
  //initialise intercom sounds vectors
  intercom_sounds_init(*m);
 
@@ -1824,10 +1835,6 @@
  // misc animations
  required_string("+Num Misc Animations:");
  stuff_int(&m->num_misc_animations);
- if (m->num_misc_animations > MAX_MISC_ANIMATIONS) {
- Warning(LOCATION, "Num Misc Animations exceeds maximum!");
- m->num_misc_animations = MAX_MISC_ANIMATIONS;
- }
 
  //initialise the misc anim vectors
  misc_anim_init(*m);
@@ -1914,10 +1921,6 @@
  // door animations
  required_string("+Num Door Animations:");
  stuff_int(&m->num_door_animations);
- if (m->num_door_animations > MAX_DOOR_ANIMATIONS) {
- Warning(LOCATION, "Num Door Animations exceeds maximum!");
- m->num_door_animations = MAX_DOOR_ANIMATIONS;
- }
 
  //initialise the door anim vectors
  door_anim_init(*m);

Apply patch straight to latest trunk. Thanks in advance!

EDIT: Silly CommanderDJ, there was a bug in your code! Fixed now (the just above has been updated to reflect the fixes). I have tested it more, including with misc anim groups and it all works as expected. If Mjn's tests turn out fine, I think this will be commit-ready.
« Last Edit: January 02, 2012, 07:50:00 am by CommanderDJ »
[16:57] <CommanderDJ> What prompted the decision to split WiH into acts?
[16:58] <battuta> it was long, we wanted to release something
[16:58] <battuta> it felt good to have a target to hit
[17:00] <RangerKarl> not sure if talking about strike mission, or jerking off
[17:00] <CommanderDJ> WUT
[17:00] <CommanderDJ> hahahahaha
[17:00] <battuta> hahahaha
[17:00] <RangerKarl> same thing really, if you think about it

 

Offline CommanderDJ

  • Software engineer
  • 210
    • Minecraft
Please note the above post was edited to reflect changes in the patch.

Now, I will probably not start work on the next change (introducing name identifiers for mainhalls) until after the 17th of January, as from the 8th I'm going on an interstate holiday until then. Name identifiers will without a doubt be the biggest change this project will introduce to the code, since they'll be replacing the mainhall number as the code's identifier for a particular mainhall. This will affect (obviously) the mainhall code, it will affect scripting, it will affect the pilot code, it will affect parts of the UI. Whilst I'm by now very familiar with the mainhall (and associated parsing) code, I've not yet touched the other three (and there's most likely other areas which I'm not yet aware that I'll hit with this). Such a widespread change will likely take some time to implement by itself, not to mention keeping backwards compatibility so I don't accidentally the game.

The parsing of the name identifier itself and its storage in the mainhall struct will be pretty easy, so I'll try and get that written up and hopefully committed before I leave on the 8th. We'll see how we go.
[16:57] <CommanderDJ> What prompted the decision to split WiH into acts?
[16:58] <battuta> it was long, we wanted to release something
[16:58] <battuta> it felt good to have a target to hit
[17:00] <RangerKarl> not sure if talking about strike mission, or jerking off
[17:00] <CommanderDJ> WUT
[17:00] <CommanderDJ> hahahahaha
[17:00] <battuta> hahahaha
[17:00] <RangerKarl> same thing really, if you think about it

 

Offline mjn.mixael

  • Cutscene Master
  • 212
  • Chopped liver
    • Steam
    • Twitter
Built on latest Trunk. CTDs on startup. Log attached.

[attachment deleted by a ninja]
Cutscene Upgrade Project - Mainhall Remakes - Between the Ashes
Youtube Channel - P3D Model Box
Between the Ashes is looking for committed testers, PM me for details.
Freespace Upgrade Project See what's happening.

 

Offline CommanderDJ

  • Software engineer
  • 210
    • Minecraft
Hello.
I'm leaving for an interstate trip tomorrow morning for 9 days. mjn.mixael's crashes still have not been resolved as I cannot seem to reproduce the problem. It does seem he's hitting an out_of_range exception thrown by an invalid .at() access, from what I can tell, but it still boggles me that I don't hit the same thing, even when we're both using retail tables. If anyone is interested, please do test to see if you also get the crash. I think it'd be helpful if we got a third opinion here (well, not opinion, but you know what I mean). I've attached a slightly updated patch to provide a little bit more detailed logging to the fs2_open.log, but it hasn't helped much in identifying the problem, unfortunately. If no one else tests by the time I get back I will do my best to debug the problem with mjn, though I'd appreciate it if a coder (or anyone, really) helped out. Thank you all for your patience.


[attachment deleted by a ninja]
[16:57] <CommanderDJ> What prompted the decision to split WiH into acts?
[16:58] <battuta> it was long, we wanted to release something
[16:58] <battuta> it felt good to have a target to hit
[17:00] <RangerKarl> not sure if talking about strike mission, or jerking off
[17:00] <CommanderDJ> WUT
[17:00] <CommanderDJ> hahahahaha
[17:00] <battuta> hahahaha
[17:00] <RangerKarl> same thing really, if you think about it

 

Offline mjn.mixael

  • Cutscene Master
  • 212
  • Chopped liver
    • Steam
    • Twitter
Good news! I'm not getting any crashes with this patch. Tried with -reparse_mainhall as well. I also tested removing +Misc Anim Handles and +Misc Anim Flags. No issues found anywhere as far as I can tell. Everything works as I would expect.
Cutscene Upgrade Project - Mainhall Remakes - Between the Ashes
Youtube Channel - P3D Model Box
Between the Ashes is looking for committed testers, PM me for details.
Freespace Upgrade Project See what's happening.

 

Offline CommanderDJ

  • Software engineer
  • 210
    • Minecraft
Oh that's brilliant! Really good news. Before I left I tested it on my end and it all worked for me too, so that's good to hear. Hopefully a coder will take a look at the patch soon and evaluate it.
[16:57] <CommanderDJ> What prompted the decision to split WiH into acts?
[16:58] <battuta> it was long, we wanted to release something
[16:58] <battuta> it felt good to have a target to hit
[17:00] <RangerKarl> not sure if talking about strike mission, or jerking off
[17:00] <CommanderDJ> WUT
[17:00] <CommanderDJ> hahahahaha
[17:00] <battuta> hahahaha
[17:00] <RangerKarl> same thing really, if you think about it

 

Offline CommanderDJ

  • Software engineer
  • 210
    • Minecraft
So I got back home last night. I will hopefully if I'm not too lazy start work on this again in the next few days. The above patch still works fine against latest trunk, so if a coder has a spare moment could it please be committed? I'll be on IRC when I'm free so I'll bug whoever's on there eventually :P.

EDIT: Limit removal patch committed by Zacam to trunk in r8267.
« Last Edit: January 19, 2012, 09:11:41 pm by CommanderDJ »
[16:57] <CommanderDJ> What prompted the decision to split WiH into acts?
[16:58] <battuta> it was long, we wanted to release something
[16:58] <battuta> it felt good to have a target to hit
[17:00] <RangerKarl> not sure if talking about strike mission, or jerking off
[17:00] <CommanderDJ> WUT
[17:00] <CommanderDJ> hahahahaha
[17:00] <battuta> hahahaha
[17:00] <RangerKarl> same thing really, if you think about it

 

Offline CommanderDJ

  • Software engineer
  • 210
    • Minecraft
Status update: I've decided to combine the last two features of dynamic mainhalls into one release. If you recall from waaay back in the thread:
Quote
3. Introducing name identifiers for mainhalls and updating the code to use these to refer to mainhalls rather than indexes, and adding the accompanying +Name flag to mainhall.tbl.
4. Changing the mainhall array to a vector and thus making mainhalls dynamic, and updating the code accordingly.

I've decided to work on both of these simultaneously since number 4 makes number 3 a lot easier in some departments, and yet I can't introduce number 4 without having number 3 in the first place because of the inherent danger in assuming specific indices for mainhalls which, when Main_hall_defines is a vector, cannot be guaranteed. I'm slowly becoming more familiar with the areas of the code I need to work with, but am still a way off from a workable understanding it. I do have a patch that can be tested, but please keep in mind this is not a finished patch. Also PLEASE NOTE that this is an ANTIPODES patch, so it must be applied to antipodes and tested there. I moved work to antipodes as per Zacam's recommendation due to the pilot and campaign file code (which I'm going to have to work with) there being much more robust. And since we're not a long way off from the pilot code being moved into trunk, why not?

Also, I'd really appreciate coder feedback on this patch so far. As I said, I'm still a bit unfamiliar, so I'd like to know if I've done anything I shouldn't or made assumptions or whatever. This patch vectorises Main_hall_defines, and introduces tabling and parsing of an optional +Name identifier for mainhall entries. Names cannot have duplicates within the same resolution. So, for example, you could have both the 640x480 and 1024x768 entries for the Aquitaine mainhall have the name "Aquitaine", but you couldn't name the Psamptik the same thing. The code will deal with it if you do make that mistake, but it will also yell at you a little bit.

Here it is:
Code: [Select]
Index: code/freespace2/freespace.cpp
===================================================================
--- code/freespace2/freespace.cpp (revision 8370)
+++ code/freespace2/freespace.cpp (working copy)
@@ -158,8 +158,6 @@
 #include "fs2netd/fs2netd_client.h"
 #include "pilotfile/pilotfile.h"
 
-#include "globalincs/pstypes.h"
-
 #include <stdexcept>
 
 extern int Om_tracker_flag; // needed for FS2OpenPXO config
Index: code/menuui/mainhallmenu.cpp
===================================================================
--- code/menuui/mainhallmenu.cpp (revision 8370)
+++ code/menuui/mainhallmenu.cpp (working copy)
@@ -58,100 +58,10 @@
 #define MISC_ANIM_MODE_TIMED 2 // uses timestamps to determine when a finished anim should be checked again
 
 #define NUM_REGIONS 7 // (6 + 1 for multiplayer equivalent of campaign room)
-typedef struct main_hall_defines {
- // bitmap and mask
- SCP_string bitmap;
- SCP_string mask;
 
- // music
- SCP_string music_name;
- SCP_string substitute_music_name;
+SCP_vector<SCP_vector<main_hall_defines> > Main_hall_defines;
+main_hall_defines *Main_hall = NULL;
 
- // intercom defines -------------------
-
- // # of intercom sounds
- int num_random_intercom_sounds;
-
- // random (min/max) delays between playing intercom sounds
- SCP_vector<SCP_vector<int> > intercom_delay;
-
- // intercom sounds themselves
- SCP_vector<int> intercom_sounds;
-
- // intercom sound pan values
- SCP_vector<float> intercom_sound_pan;
-
-
- // misc animations --------------------
-
- // # of misc animations
- int num_misc_animations;
-
- // filenames of the misc animations
- SCP_vector<SCP_string> misc_anim_name;
-
- // Time until we will next play a given misc animation, min delay, and max delay
- SCP_vector<SCP_vector<int> > misc_anim_delay;
-
- // Goober5000, used in preference to the flag in generic_anim
- SCP_vector<int> misc_anim_paused;
-
- // Goober5000, used when we want to play one of several anims
- SCP_vector<int> misc_anim_group;
-
- // coords of where to play the misc anim
- SCP_vector<SCP_vector<int> > misc_anim_coords;
-
- // misc anim play modes (see MISC_ANIM_MODE_* above)
- SCP_vector<int> misc_anim_modes;
-
- // panning values for each of the misc anims
- SCP_vector<float> misc_anim_sound_pan;
-
- //sounds for each of the misc anims
- SCP_vector<SCP_vector<int> > misc_anim_special_sounds;
-
- //frame number triggers for each of the misc anims
- SCP_vector<SCP_vector<int> > misc_anim_special_trigger;
-
- //flags for each of the misc anim sounds
- SCP_vector<SCP_vector<int> > misc_anim_sound_flag;
-
-
- // door animations --------------------
-
- // # of door animations
- int num_door_animations;
-
- // filenames of the door animations
- SCP_vector<SCP_string> door_anim_name;
-
- // first pair : coords of where to play a given door anim
- // second pair : center of a given door anim in windowed mode
- SCP_vector<SCP_vector<int> > door_anim_coords;
-
- // sounds for each region (open/close)
- SCP_vector<SCP_vector<int> > door_sounds;
-
- // pan values for the door sounds
- SCP_vector<float> door_sound_pan;
-
-
- // region descriptions ----------------
-
- // text (tooltip) description
- SCP_vector<char*> region_descript;
-
- // y coord of where to draw tooltip text
- int region_yval;
-
-} main_hall_defines;
-
-
-// use main hall 0 by default
-main_hall_defines Main_hall_defines[GR_NUM_RESOLUTIONS][MAIN_HALLS_MAX];
-main_hall_defines *Main_hall = &Main_hall_defines[0][0];
-
 int Num_main_halls = 0;
 
 int Vasudan_funny = 0;
@@ -518,7 +428,7 @@
 
  // assign the proper main hall data
  Assert((main_hall_num >= 0) && (main_hall_num < Num_main_halls));
- Main_hall = &Main_hall_defines[gr_screen.res][main_hall_num];
+ Main_hall = &Main_hall_defines.at(gr_screen.res).at(main_hall_num);
 
  // tooltip strings
  Main_hall->region_descript.at(0) = XSTR( "Exit FreeSpace 2", 353);
@@ -604,7 +514,7 @@
  }
 
  // load in help overlay bitmap
- if (Main_hall == &Main_hall_defines[gr_screen.res][0]) {
+ if (Main_hall == &Main_hall_defines.at(gr_screen.res).at(0)) {
  Main_hall_overlay_id = MH_OVERLAY;
  } else {
  //Assert(Main_hall == &Main_hall_defines[gr_screen.res][1]);
@@ -1036,7 +946,7 @@
  return -1;
  }
 
- hall = &Main_hall_defines[gr_screen.res][main_hall_num];
+ hall = &Main_hall_defines.at(gr_screen.res).at(main_hall_num);
 
  // Goober5000 - try substitute first
  index = event_music_get_spooled_music_index(hall->substitute_music_name);
@@ -1073,7 +983,7 @@
  }
 
  // get music
- index = main_hall_get_music_index(Main_hall-Main_hall_defines[gr_screen.res]);
+ index = main_hall_get_music_index(main_hall_id());
  if (index < 0) {
  nprintf(("Warning", "No music file exists to play music at the main menu!\n"));
  return;
@@ -1601,12 +1511,42 @@
  gr_string((gr_screen.max_w_unscaled - w)/2, Main_hall_tooltip_padding[gr_screen.res] /*- y_anim_offset*/, str);
 }
 
+/**
+ * CommanderDJ - finds the mainhall struct whose name is equal to the passed string
+ * @param name_to_find Name of mainhall we're searching for
+ * @param size Size of array to search
+ *
+ * \return pointer to mainhall if one with a matching name is found
+ * \return NULL otherwise
+ */
+main_hall_defines* main_hall_get_by_name(SCP_string name_to_find, int size)
+{
+ for(int i=0; i<size; i++)
+ {
+ if(Main_hall_defines.at(gr_screen.res).at(i).name == name_to_find)
+ return &Main_hall_defines.at(gr_screen.res).at(i);
+ }
+ return NULL;
+}
+
 // what main hall we're on
 int main_hall_id()
 {
  return (Main_hall - &Main_hall_defines[gr_screen.res][0]);
 }
 
+//helper function for initialising the Main_hall_defines vector
+//call before parsing mainhall.tbl
+void main_hall_defines_init()
+{
+ SCP_vector<main_hall_defines> temp;
+ //for each resolution we just want to put in a blank vector
+ for(int i=0; i<GR_NUM_RESOLUTIONS; i++)
+ {
+ Main_hall_defines.push_back(temp);
+ }
+}
+
 //CommanderDJ - helper function for initialising intercom sounds vectors based on number of sounds
 //To be called after num_intercom_sounds has been parsed
 void intercom_sounds_init(main_hall_defines &m)
@@ -1752,6 +1692,7 @@
 // read in main hall table
 void main_hall_read_table()
 {
+ SCP_vector<main_hall_defines> temp_vector;
  main_hall_defines *m, temp;
  int count, idx, s_idx, m_idx, rval;
  char temp_string[MAX_FILENAME_LEN];
@@ -1773,11 +1714,14 @@
 
  reset_parse();
 
+ main_hall_defines_init();
+
  // go for it
  count = 0;
  while (!optional_string("#end")) {
  // read in 2 resolutions
  for (m_idx=0; m_idx<GR_NUM_RESOLUTIONS; m_idx++) {
+ /*
  // maybe use a temp main hall struct
  if (count >= MAIN_HALLS_MAX) {
  m = &temp;
@@ -1786,11 +1730,33 @@
  break;
  } else {
  m = &Main_hall_defines[m_idx][count];
- }
+ }*/
 
+ Main_hall_defines.at(m_idx).push_back(temp);
+ m = &Main_hall_defines.at(m_idx).at(count);
+
  // ready
  required_string("$Main Hall");
 
+ //name. if no name is included, just give it a number
+ itoa(count, temp_string, 10);
+ m->name = temp_string;
+
+ if(optional_string("+Name:"))
+ {
+ stuff_string(temp_string, F_RAW, MAX_FILENAME_LEN);
+
+ //we can't have two mainhalls with the same name
+ if(main_hall_get_by_name(temp_string, count) == NULL)
+ {
+ m->name = temp_string;
+ }
+ else
+ {
+ Warning(LOCATION, "A mainhall with the name '%s' already exists. All mainhalls must have unique names. Setting name to %i.", temp_string, count);
+ }
+ }
+
  // bitmap and mask
  required_string("+Bitmap:");
  stuff_string(temp_string, F_NAME, MAX_FILENAME_LEN);
@@ -1959,10 +1925,8 @@
  required_string("+Tooltip Y:");
  stuff_int(&m->region_yval);
  }
-
- if (count < MAIN_HALLS_MAX) {
- count++;
- }
+
+ count++;
  }
 
  Num_main_halls = count;
@@ -1971,17 +1935,17 @@
  if (Vasudan_funny) {
  int hall = main_hall_id();
 
- Main_hall_defines[GR_640][hall].door_sounds.at(OPTIONS_REGION).at(0) = SND_VASUDAN_BUP;
- Main_hall_defines[GR_640][hall].door_sounds.at(OPTIONS_REGION).at(1) = SND_VASUDAN_BUP;
- Main_hall_defines[GR_1024][hall].door_sounds.at(OPTIONS_REGION).at(0) = SND_VASUDAN_BUP;
- Main_hall_defines[GR_1024][hall].door_sounds.at(OPTIONS_REGION).at(1) = SND_VASUDAN_BUP;
+ Main_hall_defines.at(GR_640).at(hall).door_sounds.at(OPTIONS_REGION).at(0) = SND_VASUDAN_BUP;
+ Main_hall_defines.at(GR_640).at(hall).door_sounds.at(OPTIONS_REGION).at(1) = SND_VASUDAN_BUP;
+ Main_hall_defines.at(GR_1024).at(hall).door_sounds.at(OPTIONS_REGION).at(0) = SND_VASUDAN_BUP;
+ Main_hall_defines.at(GR_1024).at(hall).door_sounds.at(OPTIONS_REGION).at(1) = SND_VASUDAN_BUP;
 
  // set head anim. hehe
- Main_hall_defines[GR_1024][hall].door_anim_name.at(OPTIONS_REGION) = "2_vhallheads";
+ Main_hall_defines.at(GR_1024).at(hall).door_anim_name.at(OPTIONS_REGION) = "2_vhallheads";
 
  // set the background
- Main_hall_defines[GR_640][hall].bitmap = "vhallhead";
- Main_hall_defines[GR_1024][hall].bitmap = "2_vhallhead";
+ Main_hall_defines.at(GR_640).at(hall).bitmap = "vhallhead";
+ Main_hall_defines.at(GR_1024).at(hall).bitmap = "2_vhallhead";
  }
 
  // free up memory from parsing the mainhall tbl
Index: code/menuui/mainhallmenu.h
===================================================================
--- code/menuui/mainhallmenu.h (revision 8370)
+++ code/menuui/mainhallmenu.h (working copy)
@@ -7,14 +7,109 @@
  *
 */
 
+#include "globalincs/globals.h"
+#include "globalincs/pstypes.h"
 
-
 #ifndef _MAIN_HALL_MENU_HEADER_FILE
 #define _MAIN_HALL_MENU_HEADER_FILE
 
 // the # of main halls we're supporting
 #define MAIN_HALLS_MAX 10 // Goober5000 - bumped down to 10; don't go above 256 (size of ubyte)
 
+typedef struct main_hall_defines {
+ // mainhall name identifier
+ SCP_string name;
+
+ // bitmap and mask
+ SCP_string bitmap;
+ SCP_string mask;
+
+ // music
+ SCP_string music_name;
+ SCP_string substitute_music_name;
+
+ // intercom defines -------------------
+
+ // # of intercom sounds
+ int num_random_intercom_sounds;
+
+ // random (min/max) delays between playing intercom sounds
+ SCP_vector<SCP_vector<int> > intercom_delay;
+
+ // intercom sounds themselves
+ SCP_vector<int> intercom_sounds;
+
+ // intercom sound pan values
+ SCP_vector<float> intercom_sound_pan;
+
+
+ // misc animations --------------------
+
+ // # of misc animations
+ int num_misc_animations;
+
+ // filenames of the misc animations
+ SCP_vector<SCP_string> misc_anim_name;
+
+ // Time until we will next play a given misc animation, min delay, and max delay
+ SCP_vector<SCP_vector<int> > misc_anim_delay;
+
+ // Goober5000, used in preference to the flag in generic_anim
+ SCP_vector<int> misc_anim_paused;
+
+ // Goober5000, used when we want to play one of several anims
+ SCP_vector<int> misc_anim_group;
+
+ // coords of where to play the misc anim
+ SCP_vector<SCP_vector<int> > misc_anim_coords;
+
+ // misc anim play modes (see MISC_ANIM_MODE_* above)
+ SCP_vector<int> misc_anim_modes;
+
+ // panning values for each of the misc anims
+ SCP_vector<float> misc_anim_sound_pan;
+
+ //sounds for each of the misc anims
+ SCP_vector<SCP_vector<int> > misc_anim_special_sounds;
+
+ //frame number triggers for each of the misc anims
+ SCP_vector<SCP_vector<int> > misc_anim_special_trigger;
+
+ //flags for each of the misc anim sounds
+ SCP_vector<SCP_vector<int> > misc_anim_sound_flag;
+
+
+ // door animations --------------------
+
+ // # of door animations
+ int num_door_animations;
+
+ // filenames of the door animations
+ SCP_vector<SCP_string> door_anim_name;
+
+ // first pair : coords of where to play a given door anim
+ // second pair : center of a given door anim in windowed mode
+ SCP_vector<SCP_vector<int> > door_anim_coords;
+
+ // sounds for each region (open/close)
+ SCP_vector<SCP_vector<int> > door_sounds;
+
+ // pan values for the door sounds
+ SCP_vector<float> door_sound_pan;
+
+
+ // region descriptions ----------------
+
+ // text (tooltip) description
+ SCP_vector<char*> region_descript;
+
+ // y coord of where to draw tooltip text
+ int region_yval;
+
+} main_hall_defines;
+
+extern SCP_vector<SCP_vector<main_hall_defines> > Main_hall_defines;
+
 // initialize the main hall proper
 void main_hall_init(int main_hall_num);
 
Index: code/menuui/playermenu.cpp
===================================================================
--- code/menuui/playermenu.cpp (revision 8370)
+++ code/menuui/playermenu.cpp (working copy)
@@ -1236,7 +1236,7 @@
  if (Dc_arg_type & ARG_INT) {
  int idx = Dc_arg_int;
 
- if (idx < 0 || idx >= MAIN_HALLS_MAX) {
+ if (idx < 0 || idx >= Main_hall_defines.at(gr_screen.res).size()) {
  dc_printf("Main hall index out of range\n");
  } else {
  Player_select_force_main_hall = idx;

[16:57] <CommanderDJ> What prompted the decision to split WiH into acts?
[16:58] <battuta> it was long, we wanted to release something
[16:58] <battuta> it felt good to have a target to hit
[17:00] <RangerKarl> not sure if talking about strike mission, or jerking off
[17:00] <CommanderDJ> WUT
[17:00] <CommanderDJ> hahahahaha
[17:00] <battuta> hahahaha
[17:00] <RangerKarl> same thing really, if you think about it

 

Offline mjn.mixael

  • Cutscene Master
  • 212
  • Chopped liver
    • Steam
    • Twitter
Things are working as I'd expect.
Cutscene Upgrade Project - Mainhall Remakes - Between the Ashes
Youtube Channel - P3D Model Box
Between the Ashes is looking for committed testers, PM me for details.
Freespace Upgrade Project See what's happening.

 

Offline Iss Mneur

  • 210
  • TODO:
Delete code that is redundant, don't comment it out, and especially don't comment it out with /* */, use #if 0 #endif because the preprocessor macros can be recursive, multi-line comments cannot.

Code: [Select]
int main_hall_id()
 {
  return (Main_hall - &Main_hall_defines[gr_screen.res][0]);
 }
I don't think this does the same thing that it did when Main_hall_defines was a struct.

Code: [Select]
+typedef struct main_hall_defines {
...
+} main_hall_defines;
+
+extern SCP_vector<SCP_vector<main_hall_defines> > Main_hall_defines;
Symbols that only differ by case strike me as a bad idea.  Also, this is C++ code, the typedef is redundant.

Otherwise, it looks okay stylewise. I haven't tested it yet.
"I love deadlines. I like the whooshing sound they make as they fly by." -Douglas Adams
wxLauncher 0.9.4 public beta (now with no config file editing for FRED) | wxLauncher 2.0 Request for Comments

 

Offline Goober5000

  • HLP Loremaster
  • Moderator
  • 214
    • Goober5000 Productions
Code: [Select]
int main_hall_id()
 {
  return (Main_hall - &Main_hall_defines[gr_screen.res][0]);
 }
I don't think this does the same thing that it did when Main_hall_defines was a struct.

Yeah, results are probably undefined if Main_hall_defines is a vector.  You could replace it with an indexof on the Main_hall variable.

 

Offline CommanderDJ

  • Software engineer
  • 210
    • Minecraft
I have rectified the main_hall_id() function.

As for the typedef, if I remove it the compiler absolutely screams at me.

Delete code that is redundant, don't comment it out, and especially don't comment it out with /* */, use #if 0 #endif because the preprocessor macros can be recursive, multi-line comments cannot.

I'm not sure I understand you on this point. Could you please elaborate? That said, I have deleted the code that is no longer being used because of my changes.

For Main_hall_defines, what would you suggest I rename it to?

In other news, I have successfully removed the need for the player::main_hall variable. Mainhalls are now loaded purely based on what campaign file is being used. All I have to do now is start enforcing use of the name identifier for them, made slightly easier by a few helper functions I've written.

Also, in removing the player::main_hall var, I broke a lua function (getMainHall I believe). Will need to see about fixing that, for now it's just commented out.
[16:57] <CommanderDJ> What prompted the decision to split WiH into acts?
[16:58] <battuta> it was long, we wanted to release something
[16:58] <battuta> it felt good to have a target to hit
[17:00] <RangerKarl> not sure if talking about strike mission, or jerking off
[17:00] <CommanderDJ> WUT
[17:00] <CommanderDJ> hahahahaha
[17:00] <battuta> hahahaha
[17:00] <RangerKarl> same thing really, if you think about it

 

Offline Iss Mneur

  • 210
  • TODO:
As for the typedef, if I remove it the compiler absolutely screams at me.
Screams about what?

Delete code that is redundant, don't comment it out, and especially don't comment it out with /* */, use #if 0 #endif because the preprocessor macros can be recursive, multi-line comments cannot.
I'm not sure I understand you on this point. Could you please elaborate? That said, I have deleted the code that is no longer being used because of my changes.
I am referring to these two added comment characters.
Code: [Select]
for (m_idx=0; m_idx<GR_NUM_RESOLUTIONS; m_idx++) {
+ /*
  // maybe use a temp main hall struct
  if (count >= MAIN_HALLS_MAX) {
  m = &temp;
@@ -1786,11 +1730,33 @@
  break;
  } else {
  m = &Main_hall_defines[m_idx][count];
- }
+ }*/
Unless I misunderstand what you want elaboration on.


For Main_hall_defines, what would you suggest I rename it to?
Rename the type to main_hall_defines_t or something.
"I love deadlines. I like the whooshing sound they make as they fly by." -Douglas Adams
wxLauncher 0.9.4 public beta (now with no config file editing for FRED) | wxLauncher 2.0 Request for Comments