예제 #1
0
// -------------------------------------------------------------------------------------------------
// gamesnd_parse_line()
//
// Parse a sound effect line
//
void gamesnd_parse_line(game_snd* gs, char* tag)
{
	int is_3d;

	required_string(tag);
	stuff_int(&gs->sig);
	stuff_string(gs->filename, F_NAME, MAX_FILENAME_LEN, ",");
	if (!stricmp(gs->filename, NOX("empty")))
	{
		gs->filename[0] = 0;
		advance_to_eoln(NULL);
		return;
	}
	Mp++;
	stuff_int(&gs->preload);
	stuff_float(&gs->default_volume);
	stuff_int(&is_3d);
	if (is_3d)
	{
		gs->flags |= GAME_SND_USE_DS3D;
		stuff_int(&gs->min);
		stuff_int(&gs->max);
	}
	else
	{
		gs->min = 0;
		gs->max = 0;
	}
	advance_to_eoln(NULL);
}
예제 #2
0
void parse_rank_tbl()
{
	atexit(scoreing_close);
	char buf[MULTITEXT_LENGTH];
	int rval, idx, persona;

	if ((rval = setjmp(parse_abort)) != 0) {
		mprintf(("TABLES: Unable to parse '%s'!  Error code = %i.\n", "rank.tbl", rval));
		return;
	} 

	read_file_text("rank.tbl", CF_TYPE_TABLES);
	reset_parse();

	// parse in all the rank names
	idx = 0;
	skip_to_string("[RANK NAMES]");
	ignore_white_space();
	while ( required_string_either("#End", "$Name:") ) {
		Assert ( idx < NUM_RANKS );
		required_string("$Name:");
		stuff_string( Ranks[idx].name, F_NAME, NAME_LENGTH );
		required_string("$Points:");
		stuff_int( &Ranks[idx].points );
		required_string("$Bitmap:");
		stuff_string( Ranks[idx].bitmap, F_NAME, MAX_FILENAME_LEN );
		required_string("$Promotion Voice Base:");
		stuff_string( Ranks[idx].promotion_voice_base, F_NAME, MAX_FILENAME_LEN );
		while (check_for_string("$Promotion Text:")) {
			required_string("$Promotion Text:");
			stuff_string(buf, F_MULTITEXT, sizeof(buf));
			drop_white_space(buf);
			compact_multitext_string(buf);
			persona = -1;
			if (optional_string("+Persona:")) {
				stuff_int(&persona);
				if (persona < 0) {
					Warning(LOCATION, "Debriefing text for %s rank is assigned to an invalid persona: %i (must be 0 or greater).\n", Ranks[idx].name, persona);
					continue;
				}
			}
			Ranks[idx].promotion_text[persona] = vm_strdup(buf);
		}
		if (Ranks[idx].promotion_text.find(-1) == Ranks[idx].promotion_text.end()) {
			Warning(LOCATION, "%s rank is missing default debriefing text.\n", Ranks[idx].name);
			Ranks[idx].promotion_text[-1] = "";
		}
		idx++;
	}

	required_string("#End");

	// be sure that all rank points are in order
#ifndef NDEBUG
	for ( idx = 0; idx < NUM_RANKS-1; idx++ ) {
		if ( Ranks[idx].points >= Ranks[idx+1].points )
			Int3();
	}
#endif
}
/* write a tx descriptor to buffer in LE byteorder */
static unsigned char*
stuff_tx_desc(unsigned char *p,
              uint32_t buf_ptr,
              uint32_t ctrl,
              uint16_t size,
              uint32_t next)
{
   p = stuff_int(p, buf_ptr, 4);
   p = stuff_int(p, ctrl, 4);
   p = stuff_int(p, size, 2);
   p = stuff_int(p, 0, 2);
   p = stuff_int(p, next, 4);
   return p;
}
static void
createDataReq(unsigned char **msg, 
              const void *payload, 
              size_t payload_size, 
              uint32_t address, 
              size_t *size)
{
   unsigned char *p;
   size_t totSize;
   size_t padding = 0;

   totSize = MAC_DATA_HDR_SIZE + payload_size;
   if(totSize < wifiEngineState.config.min_pdu_size)
      padding = wifiEngineState.config.min_pdu_size - totSize;
   if(padding > 0 && padding < 6)
      padding = 6;
#undef A
#define A(N, S) ((N) & ((S) - 1))
   if(A(totSize + padding, wifiEngineState.config.pdu_size_alignment) != 0) {
      padding += wifiEngineState.config.pdu_size_alignment 
         - A(totSize + padding, wifiEngineState.config.pdu_size_alignment);
   }
   if(padding > 0 && padding < 6)
      padding = 6;
   if(A(totSize + padding, wifiEngineState.config.pdu_size_alignment) != 0) {
      padding += wifiEngineState.config.pdu_size_alignment 
         - A(totSize + padding, wifiEngineState.config.pdu_size_alignment);
   }

   totSize += padding;
   *msg = p = (unsigned char *)DriverEnvironment_TX_Alloc(totSize);
   p = stuff_int(p, payload_size, 2);
   p = stuff_int(p, address, 4);
   DE_MEMCPY(p, payload, payload_size);
   p += payload_size;

   DE_ASSERT(padding == 0 || padding >= 6);
   if(padding > 0) {
      /* padding is at least 6 */
      p = stuff_int(p, padding - 6, 2);
      if(dump_address_table == dump_address_table_nrx600) 
         p = stuff_int(p, SAFE_ADDRESS_NRX600, 4);
      else
         p = stuff_int(p, SAFE_ADDRESS_NRX701, 4);
      DE_MEMSET(p, 0, padding - 6);
   }

   *size = totSize;
}
예제 #5
0
// game init
void ssm_init()
{
	int rval;
	ssm_info bogus, *s;
	char weapon_name[NAME_LENGTH];

	if ((rval = setjmp(parse_abort)) != 0)
	{
		mprintf(("TABLES: Unable to parse '%s'!  Error code = %i.\n", "ssm.tbl", rval));
		return;
	}

	read_file_text("ssm.tbl", CF_TYPE_TABLES);
	reset_parse();

	// parse the table
	Ssm_info_count = 0;
	while (!optional_string("#end"))
	{
		// another ssm definition
		if (optional_string("$SSM:"))
		{
			// pointer to info struct
			if (Ssm_info_count >= MAX_SSM_TYPES)
			{
				s = &bogus;
			}
			else
			{
				s = &Ssm_info[Ssm_info_count];
			}

			// name
			stuff_string(s->name, F_NAME, NAME_LENGTH);

			// stuff data
			required_string("+Weapon:");
			stuff_string(weapon_name, F_NAME, NAME_LENGTH);
			required_string("+Count:");
			stuff_int(&s->count);
			required_string("+WarpRadius:");
			stuff_float(&s->warp_radius);
			required_string("+WarpTime:");
			stuff_float(&s->warp_time);
			required_string("+Radius:");
			stuff_float(&s->radius);
			required_string("+Offset:");
			stuff_float(&s->offset);

			// see if we have a valid weapon
			s->weapon_info_index = -1;
			s->weapon_info_index = weapon_name_lookup(weapon_name);
			if (s->weapon_info_index >= 0)
			{
				// valid
				Ssm_info_count++;
			}
		}
	}
}
예제 #6
0
/**
 * CommanderDJ - Parse a list of sounds. When using this function for a table entry,
 * required_string and optional_string aren't needed, as this function deals with
 * that as its tag parameter, just make sure that the destination sound index(es) can
 * handle -1 if things don't work out.
 *
 * @param destination Vector where sound indexes are to be stored
 * @param tag Tag
 * @param object_name Name of object being parsed
 * @param flags See the parse_sound_flags enum
 *
 */
void parse_sound_list(const char* tag, SCP_vector<int>& destination, const char* object_name, parse_sound_flags flags)
{
	if(optional_string(tag))
	{
		int check=0;

		//if we're using the old format, parse the first entry separately
		if(!(flags & PARSE_SOUND_SCP_SOUND_LIST))
		{
			stuff_int(&check);
		}

		//now read the rest of the entries on the line
		for(size_t i=0; !check_for_eoln(); i++)
		{
			char buf[MAX_FILENAME_LEN];
			stuff_string_white(buf, MAX_FILENAME_LEN);

			//we do this conditionally to avoid adding needless entries when reparsing
			if(destination.size() <= i)
			{
				destination.push_back(-1);
			}

			parse_sound_core(tag, &destination.at(i), object_name, buf, flags);
		}

		//if we're using the old format, double check the size)
		if(!(flags & PARSE_SOUND_SCP_SOUND_LIST) && (destination.size() != (unsigned)check))
		{
			mprintf(("%s in '%s' has " SIZE_T_ARG " entries. This does not match entered size of %i.", tag, object_name, destination.size(), check));
		}
	}
}
예제 #7
0
// initialization stuff for cutscenes
void cutscene_init()
{
	atexit(cutscene_close);
	char buf[MULTITEXT_LENGTH];
	int rval;
    cutscene_info cutinfo;

	if ((rval = setjmp(parse_abort)) != 0) {
		mprintf(("TABLES: Unable to parse '%s'!  Error code = %i.\n", "cutscenes.tbl", rval));
		return;
	}

	read_file_text("cutscenes.tbl", CF_TYPE_TABLES);
	reset_parse();

	// parse in all the cutscenes
	Cutscenes.clear();
	skip_to_string("#Cutscenes");
	ignore_white_space();

	bool isFirstCutscene = true;

	while ( required_string_either("#End", "$Filename:") ) 
    {
		required_string("$Filename:");
		stuff_string( cutinfo.filename, F_PATHNAME, MAX_FILENAME_LEN );

		required_string("$Name:");
		stuff_string( cutinfo.name, F_NAME, NAME_LENGTH );

		required_string("$Description:");
		stuff_string(buf, F_MULTITEXT, sizeof(buf));
		drop_white_space(buf);
		compact_multitext_string(buf);
		cutinfo.description = vm_strdup(buf);

		if (optional_string("$cd:"))
			stuff_int( &cutinfo.cd );
		else
			cutinfo.cd = 0;

		cutinfo.viewable = false;

		if (isFirstCutscene) {
			isFirstCutscene = false;
			// The original code assumes the first movie is the intro, so always viewable
			cutinfo.viewable = true;
		}

		if (optional_string("$Always Viewable:")) {
			stuff_boolean(&cutinfo.viewable);
		}

        Cutscenes.push_back(cutinfo);
	}

	required_string("#End");
}
예제 #8
0
void techroom_intel_init()
{
	int rval, temp;
	static int inited = 0;

	if (inited)
		return;

	// open localization
	lcl_ext_open();

	if ((rval = setjmp(parse_abort)) != 0) {
		mprintf(("TABLES: Unable to parse '%s'!  Error code = %i.\n", "species.tbl", rval));
		lcl_ext_close();
		return;
	}
	
	read_file_text("species.tbl", CF_TYPE_TABLES);
	reset_parse();

	Intel_info_size = 0;
	while (optional_string("$Entry:")) {
		Assert(Intel_info_size < MAX_INTEL_ENTRIES);
		if (Intel_info_size >= MAX_INTEL_ENTRIES) {
			mprintf(("TECHMENU: Too many intel entries!\n"));
			break;
		}

		Intel_info[Intel_info_size].flags = IIF_DEFAULT_VALUE;

		required_string("$Name:");
		stuff_string(Intel_info[Intel_info_size].name, F_NAME, NAME_LENGTH);

		required_string("$Anim:");
		stuff_string(Intel_info[Intel_info_size].anim_filename, F_NAME, NAME_LENGTH);

		required_string("$AlwaysInTechRoom:");
		stuff_int(&temp);
		if (temp) {
			// set default to align with what we read - Goober5000
			Intel_info[Intel_info_size].flags |= IIF_IN_TECH_DATABASE;
			Intel_info[Intel_info_size].flags |= IIF_DEFAULT_IN_TECH_DATABASE;
		}

		required_string("$Description:");
		stuff_string(Intel_info[Intel_info_size].desc, F_MULTITEXT, TECH_INTEL_DESC_LEN);

		Intel_info_size++;
	}

	inited = 1;

	// close localization
	lcl_ext_close();
}
static void
createDataReq_u32(unsigned char **msg, 
                  uint32_t payload, 
                  uint32_t address, 
                  size_t *size)
{
   unsigned char buf[4];

   stuff_int(buf, payload, sizeof(buf));
   createDataReq(msg, buf, sizeof(buf), address, size);
}
예제 #10
0
void techroom_intel_init()
{
	int  temp;
	static int inited = 0;

	if (inited)
		return;
		
	try
	{
		read_file_text("species.tbl", CF_TYPE_TABLES);
		reset_parse();

		Intel_info_size = 0;
		while (optional_string("$Entry:")) {
			Assert(Intel_info_size < MAX_INTEL_ENTRIES);
			if (Intel_info_size >= MAX_INTEL_ENTRIES) {
				mprintf(("TECHMENU: Too many intel entries!\n"));
				break;
			}

			Intel_info[Intel_info_size].flags = IIF_DEFAULT_VALUE;

			required_string("$Name:");
			stuff_string(Intel_info[Intel_info_size].name, F_NAME, NAME_LENGTH);

			required_string("$Anim:");
			stuff_string(Intel_info[Intel_info_size].anim_filename, F_NAME, NAME_LENGTH);

			required_string("$AlwaysInTechRoom:");
			stuff_int(&temp);
			if (temp) {
				// set default to align with what we read - Goober5000
				Intel_info[Intel_info_size].flags |= IIF_IN_TECH_DATABASE;
				Intel_info[Intel_info_size].flags |= IIF_DEFAULT_IN_TECH_DATABASE;
			}

			required_string("$Description:");
			stuff_string(Intel_info[Intel_info_size].desc, F_MULTITEXT, TECH_INTEL_DESC_LEN);

			Intel_info_size++;
		}

		inited = 1;
	}
	catch (const parse::ParseException& e)
	{
		mprintf(("TABLES: Unable to parse '%s'!  Error message = %s.\n", "species.tbl", e.what()));
		return;
	}
}
예제 #11
0
// game init
void ssm_init()
{	
	ssm_info bogus, *s;
	char weapon_name[NAME_LENGTH+1] = "";

	read_file_text("ssm.tbl");
	reset_parse();

	// parse the table
	Ssm_info_count = 0;
	while(!optional_string("#end")){
		// another ssm definition
		if(optional_string("$SSM:")){
			// pointer to info struct
			if(Ssm_info_count >= MAX_SSM_TYPES){
				s = &bogus;
			} else {
				s = &Ssm_info[Ssm_info_count];
			}

			// name
			stuff_string(s->name, F_NAME, NULL);

			// stuff data
			required_string("+Weapon:");
			stuff_string(weapon_name, F_NAME, NULL);
			required_string("+Count:");
			stuff_int(&s->count);
			required_string("+WarpRadius:");
			stuff_float(&s->warp_radius);
			required_string("+WarpTime:");
			stuff_float(&s->warp_time);
			required_string("+Radius:");
			stuff_float(&s->radius);
			required_string("+Offset:");
			stuff_float(&s->offset);

			// see if we have a valid weapon
			s->weapon_info_index = -1;
			s->weapon_info_index = weapon_name_lookup(weapon_name);
			if(s->weapon_info_index >= 0){
				// valid
				Ssm_info_count++;
			}
		}
	}
}
예제 #12
0
// initialization stuff for cutscenes
void cutscene_init()
{
	char buf[MULTITEXT_LENGTH];
	int rval;

	if ((rval = setjmp(parse_abort)) != 0) {
		Error(LOCATION, "Error parsing 'rank.tbl'\r\nError code = %i.\r\n", rval);
	} 

	// open localization
	lcl_ext_open();

	read_file_text("cutscenes.tbl");
	reset_parse();

	// parse in all the rank names
	Num_cutscenes = 0;
	skip_to_string("#Cutscenes");
	ignore_white_space();
	while ( required_string_either("#End", "$Filename:") ) {
		Assert ( Num_cutscenes < MAX_CUTSCENES );
		required_string("$Filename:");
		stuff_string( Cutscenes[Num_cutscenes].filename, F_PATHNAME, NULL );
		required_string("$Name:");
		stuff_string( Cutscenes[Num_cutscenes].name, F_NAME, NULL );
		required_string("$Description:");
		stuff_string(buf, F_MULTITEXT, NULL);
		drop_white_space(buf);
		compact_multitext_string(buf);
		Cutscenes[Num_cutscenes].description = strdup(buf);
		required_string("$cd:");
		stuff_int( &Cutscenes[Num_cutscenes].cd );

		Num_cutscenes++;
	}

	required_string("#End");

	Cutscenes_viewable = INTRO_CUTSCENE_FLAG;

	// close localization
	lcl_ext_close();
}
예제 #13
0
void parse_ssm(const char *filename)
{
	char weapon_name[NAME_LENGTH];

	try
	{
		read_file_text(filename, CF_TYPE_TABLES);
		reset_parse();

		// parse the table
		while(required_string_either("#end", "$SSM:")) {
			required_string("$SSM:");
			ssm_info s;
			int string_index;

			// name
			stuff_string(s.name, F_NAME, NAME_LENGTH);
			if (*s.name == 0) {
				sprintf(s.name, "SSM " SIZE_T_ARG, Ssm_info.size());
				mprintf(("Found an SSM entry without a name.  Assigning \"%s\".\n", s.name));
			}

			// stuff data
			required_string("+Weapon:");
			stuff_string(weapon_name, F_NAME, NAME_LENGTH);

			string_index = optional_string_either("+Count:", "+Min Count:");
			if (string_index == 0) {
				stuff_int(&s.count);
				s.max_count = -1;
			} else if (string_index == 1) {
				stuff_int(&s.count);
				required_string("+Max Count:");
				stuff_int(&s.max_count);
			} else {
				s.count = 1;
				s.max_count = -1;
			}

			required_string("+WarpRadius:");
			stuff_float(&s.warp_radius);

			if (optional_string("+WarpTime:")) {
				stuff_float(&s.warp_time);
				// According to fireballs.cpp, "Warp lifetime must be at least 4 seconds!"
				if ( (s.warp_time) < 4.0f) {
					// So let's warn them before they try to use it, shall we?
					Warning(LOCATION, "Expected a '+WarpTime:' value equal or greater than 4.0, found '%f' in weapon '%s'.\n Setting to 4.0, please check and set to a number 4.0 or greater!\n", s.warp_time, weapon_name);
					// And then make the Assert obsolete -- Zacam
					s.warp_time = 4.0f;
				}
			} else {
				s.warp_time = 4.0f;
			}

			string_index = required_string_either("+Radius:", "+Min Radius:");
			if (string_index == 0) {
				required_string("+Radius:");
				stuff_float(&s.radius);
				s.max_radius = -1.0f;
			} else {
				required_string("+Min Radius:");
				stuff_float(&s.radius);
				required_string("+Max Radius:");
				stuff_float(&s.max_radius);
			}

			string_index = optional_string_either("+Offset:", "+Min Offset:");
			if (string_index == 0) {
				stuff_float(&s.offset);
				s.max_offset = -1.0f;
			} else if (string_index == 1) {
				stuff_float(&s.offset);
				required_string("+Max Offset:");
				stuff_float(&s.max_offset);
			} else {
				s.offset = 0.0f;
				s.max_offset = -1.0f;
			}
			
			if (optional_string("+Shape:")) {
				switch(required_string_one_of(3, "Point", "Circle", "Sphere")) {
				case 0:
					required_string("Point");
					s.shape = SSM_SHAPE_POINT;
					break;
				case 1:
					required_string("Circle");
				case -1:	// If we're ignoring parse errors and can't identify the shape, go with a circle.
					s.shape = SSM_SHAPE_CIRCLE;
					break;
				case 2:
					required_string("Sphere");
					s.shape = SSM_SHAPE_SPHERE;
					break;
				default:
					Assertion(false, "Impossible return value from required_string_one_of(); get a coder!\n");
				}
			} else {
				s.shape = SSM_SHAPE_CIRCLE;
			}

			if (optional_string("+HUD Message:"))
				stuff_boolean(&s.send_message);
			else
				s.send_message = true;

			if (optional_string("+Custom Message:")) {
				stuff_string(s.message, F_NAME, NAME_LENGTH);
				s.use_custom_message = true;
			}

			s.sound_index = -1;
			parse_sound("+Alarm Sound:", &s.sound_index, s.name);

			// see if we have a valid weapon
			s.weapon_info_index = weapon_info_lookup(weapon_name);
			if(s.weapon_info_index >= 0) {
				// valid
				int existing = ssm_info_lookup(s.name);
				if (existing >= 0) {	// Redefined the existing entry instead of adding a duplicate.
					Ssm_info[existing] = s;
				} else {
					Ssm_info.push_back(s);
				}
			}
		}
	}
	catch (const parse::ParseException& e)
	{
		mprintf(("TABLES: Unable to parse '%s'!  Error message = %s.\n", filename, e.what()));
		return;
	}
}
예제 #14
0
void parse_medal_tbl()
{
	int i;

	try
	{
		read_file_text("medals.tbl", CF_TYPE_TABLES);
		reset_parse();

		required_string("#Medals");

		// special background information
		if (optional_string("+Background Bitmap:")) {
			stuff_string(Medals_background_filename, F_NAME, NAME_LENGTH);
		}
		else {
			strcpy_s(Medals_background_filename, Default_medals_background_filename);
		}

		// special mask information
		if (optional_string("+Mask Bitmap:")) {
			stuff_string(Medals_mask_filename, F_NAME, NAME_LENGTH);
		}
		else {
			strcpy_s(Medals_mask_filename, Default_medals_mask_filename);
		}

		// configurable hotspot for the exit button
		if (optional_string("+Exit Button Hotspot Index:")) {
			stuff_int(&Exit_button_hotspot_override);
		}

		// special positioning for player callsign
		if (optional_string("+Callsign Position 640:")) {
			stuff_int(&Medals_callsign_coords[GR_640].x);
			stuff_int(&Medals_callsign_coords[GR_640].y);
		}
		else {
			Medals_callsign_coords[GR_640].x = Default_medals_callsign_coords[GR_640][0];
			Medals_callsign_coords[GR_640].y = Default_medals_callsign_coords[GR_640][1];
		}
		if (optional_string("+Callsign Position 1024:")) {
			stuff_int(&Medals_callsign_coords[GR_1024].x);
			stuff_int(&Medals_callsign_coords[GR_1024].y);
		}
		else {
			Medals_callsign_coords[GR_1024].x = Default_medals_callsign_coords[GR_1024][0];
			Medals_callsign_coords[GR_1024].y = Default_medals_callsign_coords[GR_1024][1];
		}

		// special positioning for medal label
		if (optional_string("+Label Position 640:")) {
			stuff_int(&Medals_label_coords[GR_640].x);
			stuff_int(&Medals_label_coords[GR_640].y);
			stuff_int(&Medals_label_coords[GR_640].w);
		}
		else {
			Medals_label_coords[GR_640].x = Default_medals_label_coords[GR_640][0];
			Medals_label_coords[GR_640].y = Default_medals_label_coords[GR_640][1];
			Medals_label_coords[GR_640].w = Default_medals_label_coords[GR_640][2];
		}
		if (optional_string("+Label Position 1024:")) {
			stuff_int(&Medals_label_coords[GR_1024].x);
			stuff_int(&Medals_label_coords[GR_1024].y);
			stuff_int(&Medals_label_coords[GR_1024].w);
		}
		else {
			Medals_label_coords[GR_1024].x = Default_medals_label_coords[GR_1024][0];
			Medals_label_coords[GR_1024].y = Default_medals_label_coords[GR_1024][1];
			Medals_label_coords[GR_1024].w = Default_medals_label_coords[GR_1024][2];
		}

		// parse in all the medal names
		Num_medals = 0;
		while (required_string_either("#End", "$Name:"))
		{
			medal_stuff temp_medal;
			medal_display_info temp_display;

			required_string("$Name:");
			stuff_string(temp_medal.name, F_NAME, NAME_LENGTH);

			// is this rank?  if so, save it
			if (!stricmp(temp_medal.name, "Rank"))
				Rank_medal_index = Num_medals;

			required_string("$Bitmap:");
			stuff_string(temp_medal.bitmap, F_NAME, MAX_FILENAME_LEN);

			if (optional_string("+Position 640:")) {
				stuff_int(&temp_display.coords[GR_640].x);
				stuff_int(&temp_display.coords[GR_640].y);
			}
			else if (Num_medals < NUM_MEDALS_FS2) {
				temp_display.coords[GR_640].x = Default_medal_coords[GR_640][Num_medals][0];
				temp_display.coords[GR_640].y = Default_medal_coords[GR_640][Num_medals][1];
			}
			else {
				Warning(LOCATION, "No default GR_640 position for medal '%s'!", temp_medal.name);
				temp_display.coords[GR_640].x = 0;
				temp_display.coords[GR_640].y = 0;
			}
			if (optional_string("+Position 1024:")) {
				stuff_int(&temp_display.coords[GR_1024].x);
				stuff_int(&temp_display.coords[GR_1024].y);
			}
			else if (Num_medals < NUM_MEDALS_FS2) {
				temp_display.coords[GR_1024].x = Default_medal_coords[GR_1024][Num_medals][0];
				temp_display.coords[GR_1024].y = Default_medal_coords[GR_1024][Num_medals][1];
			}
			else {
				Warning(LOCATION, "No default GR_1024 position for medal '%s'!", temp_medal.name);
				temp_display.coords[GR_1024].x = 0;
				temp_display.coords[GR_1024].y = 0;
			}

			if (optional_string("+Debriefing Bitmap:")) {
				stuff_string(temp_medal.debrief_bitmap, F_NAME, MAX_FILENAME_LEN);
			}
			else if (Num_medals < NUM_MEDALS_FS2) {
				strcpy_s(temp_medal.debrief_bitmap, Default_debriefing_bitmaps[Num_medals]);
			}
			else {
				Warning(LOCATION, "No default debriefing bitmap for medal '%s'!", temp_medal.name);
				strcpy_s(temp_medal.debrief_bitmap, "");
			}

			required_string("$Num mods:");
			stuff_int(&temp_medal.num_versions);

			// this is dumb
			temp_medal.version_starts_at_1 = (Num_medals == Rank_medal_index);
			if (optional_string("+Version starts at 1:")) {
				stuff_boolean(&temp_medal.version_starts_at_1);
			}

			if (optional_string("+Available From Start:")) {
				stuff_boolean(&temp_medal.available_from_start);
			}

			// some medals are based on kill counts.  When string +Num Kills: is present, we know that
			// this medal is a badge and should be treated specially
			if (optional_string("+Num Kills:")) {
				char buf[MULTITEXT_LENGTH];
				int persona;
				stuff_int(&temp_medal.kills_needed);

				if (optional_string("$Wavefile 1:"))
					stuff_string(temp_medal.voice_base, F_NAME, MAX_FILENAME_LEN);

				if (optional_string("$Wavefile 2:"))
					stuff_string(temp_medal.voice_base, F_NAME, MAX_FILENAME_LEN);

				if (optional_string("$Wavefile Base:"))
					stuff_string(temp_medal.voice_base, F_NAME, MAX_FILENAME_LEN);

				while (check_for_string("$Promotion Text:")) {
					required_string("$Promotion Text:");
					stuff_string(buf, F_MULTITEXT, sizeof(buf));
					persona = -1;
					if (optional_string("+Persona:")) {
						stuff_int(&persona);
						if (persona < 0) {
							Warning(LOCATION, "Debriefing text for %s is assigned to an invalid persona: %i (must be 0 or greater).\n", temp_medal.name, persona);
							continue;
						}
					}
					temp_medal.promotion_text[persona] = SCP_string(buf);
				}
				if (temp_medal.promotion_text.find(-1) == temp_medal.promotion_text.end()) {
					Warning(LOCATION, "%s medal is missing default debriefing text.\n", temp_medal.name);
					temp_medal.promotion_text[-1] = "";
				}
			}

			Medals.push_back(temp_medal);
			Medal_display_info.push_back(temp_display);
			Num_medals++;
		}

		required_string("#End");

		// be sure that we know where the rank is
		if (Rank_medal_index < 0)
		{
			Warning(LOCATION, "Could not find the 'Rank' medal!");
			Rank_medal_index = 0;
		}

		// be sure that the badges kill numbers show up in order
		//WMC - I don't think this is needed anymore due to my changes to post-mission functions
		//but I'm keeping it here to be sure.
		int prev_badge_kills = 0;
		for (i = 0; i < Num_medals; i++)
		{
			if (Medals[i].kills_needed < prev_badge_kills && Medals[i].kills_needed != 0)
				Error(LOCATION, "Badges must appear sorted by lowest kill # first in medals.tbl\nFind Allender for most information.");

			if (Medals[i].kills_needed > 0)
				prev_badge_kills = Medals[i].kills_needed;
		}
	}
	catch (const parse::ParseException& e)
	{
		mprintf(("TABLES: Unable to parse '%s'!  Error message = %s.\n", "medals.tbl", e.what()));
		return;
	}
}
/**
 * @brief Parses controlconfigdefault.tbl, and overrides the default control configuration for each valid entry in the .tbl
 */
void control_config_common_load_overrides()
{
	LoadEnumsIntoMaps();

	try {
		if (cf_exists_full("controlconfigdefaults.tbl", CF_TYPE_TABLES)) {
			read_file_text("controlconfigdefaults.tbl", CF_TYPE_TABLES);
		} else {
			read_file_text_from_default(defaults_get_file("controlconfigdefaults.tbl"));
		}

		reset_parse();

		// start parsing
		// TODO: Split this out into more helps. Too many tabs!
		while(optional_string("#ControlConfigOverride")) {
			config_item *cfg_preset = new config_item[CCFG_MAX + 1];
			std::copy(Control_config, Control_config + CCFG_MAX + 1, cfg_preset);
			Control_config_presets.push_back(cfg_preset);

			SCP_string preset_name;
			if (optional_string("$Name:")) {
				stuff_string_line(preset_name);
			} else {
				preset_name = "<unnamed preset>";
			}
			Control_config_preset_names.push_back(preset_name);

			while (required_string_either("#End","$Bind Name:")) {
				const int iBufferLength = 64;
				char szTempBuffer[iBufferLength];

				required_string("$Bind Name:");
				stuff_string(szTempBuffer, F_NAME, iBufferLength);

				const size_t cCntrlAryLength = sizeof(Control_config) / sizeof(Control_config[0]);
				for (size_t i = 0; i < cCntrlAryLength; ++i) {
					config_item& r_ccConfig = cfg_preset[i];

					if (!strcmp(szTempBuffer, r_ccConfig.text)) {
						/**
                        * short key_default;
                        * short joy_default;
                        * char tab;
                        * bool hasXSTR;
                        * char type;
                        */

						int iTemp;

						if (optional_string("$Key Default:")) {
							if (optional_string("NONE")) {
								r_ccConfig.key_default = (short)-1;
							} else {
								stuff_string(szTempBuffer, F_NAME, iBufferLength);
								r_ccConfig.key_default = (short)mKeyNameToVal[szTempBuffer];
							}
						}

						if (optional_string("$Joy Default:")) {
							stuff_int(&iTemp);
							r_ccConfig.joy_default = (short)iTemp;
						}

						if (optional_string("$Key Mod Shift:")) {
							stuff_int(&iTemp);
							r_ccConfig.key_default |= (iTemp == 1) ? KEY_SHIFTED : 0;
						}

						if (optional_string("$Key Mod Alt:")) {
							stuff_int(&iTemp);
							r_ccConfig.key_default |= (iTemp == 1) ? KEY_ALTED : 0;
						}

						if (optional_string("$Key Mod Ctrl:")) {
							stuff_int(&iTemp);
							r_ccConfig.key_default |= (iTemp == 1) ? KEY_CTRLED : 0;
						}

						if (optional_string("$Category:")) {
							stuff_string(szTempBuffer, F_NAME, iBufferLength);
							r_ccConfig.tab = (char)mCCTabNameToVal[szTempBuffer];
						}

						if (optional_string("$Has XStr:")) {
							stuff_int(&iTemp);
							r_ccConfig.hasXSTR = (iTemp == 1);
						}

						if (optional_string("$Type:")) {
							stuff_string(szTempBuffer, F_NAME, iBufferLength);
							r_ccConfig.type = (char)mCCTypeNameToVal[szTempBuffer];
						}

						if (optional_string("+Disable")) {
							r_ccConfig.disabled = true;
						}
						if (optional_string("$Disable:")) {
							stuff_boolean(&r_ccConfig.disabled);
						}

						// Nerf the buffer now.
						szTempBuffer[0] = '\0';
					} else if ((i + 1) == cCntrlAryLength) {
						error_display(1, "Bind Name not found: %s\n", szTempBuffer);
						advance_to_eoln(NULL);
						ignore_white_space();
						return;
					}
				}
			}

			required_string("#End");
		}
	}
	catch (const parse::ParseException& e)
	{
		mprintf(("TABLES: Unable to parse 'controlconfigdefaults.tbl'!  Error message = %s.\n", e.what()));
		return;
	}

	// Overwrite the control config with the first preset that was found
	if (!Control_config_presets.empty()) {
		std::copy(Control_config_presets[0], Control_config_presets[0] + CCFG_MAX + 1, Control_config);
	}
}
예제 #16
0
void parse_mod_table(const char *filename)
{
	// SCP_vector<SCP_string> lines;

	try
	{
		if (filename == NULL)
			read_file_text_from_default(defaults_get_file("game_settings.tbl"));
		else
			read_file_text(filename, CF_TYPE_TABLES);

		reset_parse();

		// start parsing
		optional_string("#GAME SETTINGS");
		
		if (optional_string("$Minimum version:")) {
			int major = 0;
			int minor = 0;
			int build = 0;
			int revision = 0;
			
			required_string("+Major:");
			stuff_int(&major);
			
			required_string("+Minor:");
			stuff_int(&minor);
			
			required_string("+Build:");
			stuff_int(&build);
			
			if (optional_string("+Revision:")) {
				stuff_int(&revision);
			}
			
			mprintf(("Game Settings Table: Parsed minimum version of %s\n", version::format_version(major, minor, build, revision).c_str()));
			
			if (!version::check_at_least(major, minor, build, revision)) {
				Error(LOCATION, "This modification needs at least version %s of FreeSpace Open. However, the current is only %s!",
					  version::format_version(major, minor, build, revision).c_str(),
					  version::format_version(FS_VERSION_MAJOR, FS_VERSION_MINOR, FS_VERSION_BUILD, FS_VERSION_REVIS).c_str());
			}
		}
		
		optional_string("#CAMPAIGN SETTINGS");

		if (optional_string("$Default Campaign File Name:")) {
			char temp[MAX_FILENAME_LEN];
			stuff_string(temp, F_NAME, MAX_FILENAME_LEN);

			// remove extension?
			if (drop_extension(temp)) {
				mprintf(("Game Settings Table: Removed extension on default campaign file name %s\n", temp));
			}

			// check length
			size_t maxlen = (MAX_FILENAME_LEN - 4);
			auto len = strlen(temp);
			if (len > maxlen) {
				Warning(LOCATION, "Token too long: [%s].  Length = " SIZE_T_ARG ".  Max is " SIZE_T_ARG ".\n", temp, len, maxlen);
				temp[maxlen] = 0;
			}

			strcpy_s(Default_campaign_file_name, temp);
		}

		if (optional_string("#Ignored Campaign File Names")) {
			SCP_string campaign_name;

			while (optional_string("$Campaign File Name:")) {
				stuff_string(campaign_name, F_NAME);

				// remove extension?
				if (drop_extension(campaign_name)) {
					mprintf(("Game Settings Table: Removed extension on ignored campaign file name %s\n", campaign_name.c_str()));
				}

				Ignored_campaigns.push_back(campaign_name);
			}
		}

		if (optional_string("$Red-alert applies to delayed ships:")) {
			stuff_boolean(&Red_alert_applies_to_delayed_ships);
			if (Red_alert_applies_to_delayed_ships) {
				mprintf(("Game Settings Table: Red-alert stats will be loaded for ships that arrive later in missions\n"));
			}
			else {
				mprintf(("Game Settings Table: Red-alert stats will NOT be loaded for ships that arrive later in missions (this is retail behavior)\n"));
			}
		}

		optional_string("#HUD SETTINGS");

		// how long should the game wait before displaying a directive?
		if (optional_string("$Directive Wait Time:")) {
			stuff_int(&Directive_wait_time);
		}

		if (optional_string("$Cutscene camera displays HUD:")) {
			stuff_boolean(&Cutscene_camera_displays_hud);
		}
		// compatibility
		if (optional_string("$Cutscene camera disables HUD:")) {
			mprintf(("Game Settings Table: \"$$Cutscene camera disables HUD\" is deprecated in favor of \"$Cutscene camera displays HUD\"\n"));
			bool temp;
			stuff_boolean(&temp);
			Cutscene_camera_displays_hud = !temp;
		}

		if (optional_string("$Full color head animations:")) {
			stuff_boolean(&Full_color_head_anis);
		}
		// compatibility
		if (optional_string("$Color head animations with hud colors:")) {
			mprintf(("Game Settings Table: \"$Color head animations with hud colors\" is deprecated in favor of \"$Full color head animations\"\n"));
			bool temp;
			stuff_boolean(&temp);
			Full_color_head_anis = !temp;
		}

		optional_string("#SEXP SETTINGS");

		if (optional_string("$Loop SEXPs Then Arguments:")) {
			stuff_boolean(&True_loop_argument_sexps);
			if (True_loop_argument_sexps) {
				mprintf(("Game Settings Table: Using Reversed Loops For SEXP Arguments\n"));
			}
			else {
				mprintf(("Game Settings Table: Using Standard Loops For SEXP Arguments\n"));
			}
		}

		if (optional_string("$Use Alternate Chaining Behavior:")) {
			stuff_boolean(&Alternate_chaining_behavior);
			if (Alternate_chaining_behavior) {
				mprintf(("Game Settings Table: Using alternate event chaining behavior\n"));
			}
			else {
				mprintf(("Game Settings Table: Using standard event chaining behavior\n"));
			}
		}

		optional_string("#GRAPHICS SETTINGS");

		if (optional_string("$Enable External Shaders:")) {
			stuff_boolean(&Enable_external_shaders);
			if (Enable_external_shaders)
				mprintf(("Game Settings Table: External shaders are enabled\n"));
			else
				mprintf(("Game Settings Table: External shaders are DISABLED\n"));
		}

		if (optional_string("$Default Detail Level:")) {
			int detail_level;

			stuff_int(&detail_level);

			mprintf(("Game Settings Table: Setting default detail level to %i of %i-%i\n", detail_level, 0, NUM_DEFAULT_DETAIL_LEVELS - 1));

			if (detail_level < 0 || detail_level > NUM_DEFAULT_DETAIL_LEVELS - 1) {
				Warning(LOCATION, "Invalid detail level: %i, setting to %i\n", detail_level, Default_detail_level);
			}
			else {
				Default_detail_level = detail_level;
			}
		}

		if (optional_string("$Briefing Window FOV:")) {
			float fov;

			stuff_float(&fov);

			mprintf(("Game Settings Table: Setting briefing window FOV from %f to %f\n", Briefing_window_FOV, fov));

			Briefing_window_FOV = fov;
		}

		
			if (optional_string("$Generic Pain Flash Factor:")) {
			stuff_float(&Generic_pain_flash_factor);
			if (Generic_pain_flash_factor != 1.0f)
				mprintf(("Game Settings Table: Setting generic pain flash factor to %.2f\n", Generic_pain_flash_factor));
			
		}
		
			if (optional_string("$Shield Pain Flash Factor:")) {
			stuff_float(&Shield_pain_flash_factor);
			if (Shield_pain_flash_factor != 0.0f)
				 mprintf(("Game Settings Table: Setting shield pain flash factor to %.2f\n", Shield_pain_flash_factor));
			
		}

		optional_string("#NETWORK SETTINGS");

		if (optional_string("$FS2NetD port:")) {
			stuff_int(&FS2NetD_port);
			if (FS2NetD_port)
				mprintf(("Game Settings Table: FS2NetD connecting to port %i\n", FS2NetD_port));
		}

		optional_string("#SOUND SETTINGS");

		if (optional_string("$Default Sound Volume:")) {
			stuff_float(&Master_sound_volume);
		}

		if (optional_string("$Default Music Volume:")) {
			stuff_float(&Master_event_music_volume);
		}

		if (optional_string("$Default Voice Volume:")) {
			stuff_float(&Master_voice_volume);
		}

		optional_string("#FRED SETTINGS");

		if (optional_string("$Disable Hard Coded Message Head Ani Files:")) {
			stuff_boolean(&Disable_hc_message_ani);
			if (Disable_hc_message_ani) {
				mprintf(("Game Settings Table: FRED - Disabling Hard Coded Message Ani Files\n"));
			}
			else {
				mprintf(("Game Settings Table: FRED - Using Hard Coded Message Ani Files\n"));

			}
		}

		optional_string("#OTHER SETTINGS");

		if (optional_string("$Fixed Turret Collisions:")) {
			stuff_boolean(&Fixed_turret_collisions);
		}

		if (optional_string("$Damage Impacted Subsystem First:")) {
			stuff_boolean(&Damage_impacted_subsystem_first);
		}

		if (optional_string("$Default ship select effect:")) {
			char effect[NAME_LENGTH];
			stuff_string(effect, F_NAME, NAME_LENGTH);
			if (!stricmp(effect, "FS2"))
				Default_ship_select_effect = 2;
			else if (!stricmp(effect, "FS1"))
				Default_ship_select_effect = 1;
			else if (!stricmp(effect, "off"))
				Default_ship_select_effect = 0;
		}

		if (optional_string("$Default weapon select effect:")) {
			char effect[NAME_LENGTH];
			stuff_string(effect, F_NAME, NAME_LENGTH);
			if (!stricmp(effect, "FS2"))
				Default_weapon_select_effect = 2;
			else if (!stricmp(effect, "FS1"))
				Default_weapon_select_effect = 1;
			else if (!stricmp(effect, "off"))
				Default_weapon_select_effect = 0;
		}

		if (optional_string("$Weapons inherit parent collision group:")) {
			stuff_boolean(&Weapons_inherit_parent_collision_group);
			if (Weapons_inherit_parent_collision_group)
				mprintf(("Game Settings Table: Weapons inherit parent collision group\n"));
		}

		if (optional_string("$Flight controls follow eyepoint orientation:")) {
			stuff_boolean(&Flight_controls_follow_eyepoint_orientation);
			if (Flight_controls_follow_eyepoint_orientation)
				mprintf(("Game Settings Table: Flight controls follow eyepoint orientation\n"));
		}

		if (optional_string("$Beams Use Damage Factors:")) {
			stuff_boolean(&Beams_use_damage_factors);
			if (Beams_use_damage_factors) {
				mprintf(("Game Settings Table: Beams will use Damage Factors\n"));
			}
			else {
				mprintf(("Game Settings Table: Beams will ignore Damage Factors (retail behavior)\n"));
			}
		}

		if (optional_string("$Default fiction viewer UI:")) {
			char ui_name[NAME_LENGTH];
			stuff_string(ui_name, F_NAME, NAME_LENGTH);
			if (!stricmp(ui_name, "auto"))
				Default_fiction_viewer_ui = -1;
			else {
				int ui_index = fiction_viewer_ui_name_to_index(ui_name);
				if (ui_index >= 0)
					Default_fiction_viewer_ui = ui_index;
				else
					Warning(LOCATION, "Unrecognized fiction viewer UI: %s", ui_name);
			}
		}

		required_string("#END");
	}
	catch (const parse::ParseException& e)
	{
		mprintf(("TABLES: Unable to parse '%s'!  Error message = %s.\n", (filename) ? filename : "<default game_settings.tbl>", e.what()));
		return;
	}
}
예제 #17
0
// Unified function for loading strings.tbl and tstrings.tbl (and their modular versions).
// The "external" parameter controls which format to load: true for tstrings.tbl, false for strings.tbl
void parse_stringstbl_common(const char *filename, const bool external)
{
	char chr, buf[4096];
	char language_tag[512];
	int z, index;
	char *p_offset = NULL;
	int offset_lo = 0, offset_hi = 0;

	read_file_text(filename, CF_TYPE_TABLES);
	reset_parse();

	// move down to the proper section		
	memset(language_tag, 0, sizeof(language_tag));
	strcpy_s(language_tag, "#");
	if (external && Lcl_current_lang == FS2_OPEN_DEFAULT_LANGUAGE){
		strcat_s(language_tag, "default");
	} else {
		strcat_s(language_tag, Lcl_languages[Lcl_current_lang].lang_name);
	}

	if ( skip_to_string(language_tag) != 1 ) {
		mprintf(("Current language not found in %s\n", filename));
		return;
	}

	// parse all the strings in this section of the table
	while ( !check_for_string("#") ) {
		int num_offsets_on_this_line = 0;

		stuff_int(&index);
		if (external) {
			ignore_white_space();
			get_string(buf, sizeof(buf));
			drop_trailing_white_space(buf);
		} else {
			stuff_string(buf, F_RAW, sizeof(buf));
		}

		if (external && (index < 0 || index >= LCL_MAX_STRINGS)) {
			error_display(0, "Invalid tstrings table index specified (%i). Please increment LCL_MAX_STRINGS in localize.cpp.", index);
			return;
		} else if (!external && (index < 0 || index >= XSTR_SIZE)) {
			Error(LOCATION, "Invalid strings table index specified (%i)", index);
		}
		
		if (!external) {
			size_t i = strlen(buf);

			while (i--) {
				if ( !isspace(buf[i]) )
					break;
			}

			// trim unnecessary end of string
			// Assert(buf[i] == '"');
			if (buf[i] != '"') {
				// probably an offset on this entry

				// drop down a null terminator (prolly unnecessary)
				buf[i+1] = 0;

				// back up over the potential offset
				while ( !is_white_space(buf[i]) )
					i--;

				// now back up over intervening spaces
				while ( is_white_space(buf[i]) )
					i--;

				num_offsets_on_this_line = 1;

				if (buf[i] != '"') {
					// could have a 2nd offset value (one for 640, one for 1024)
					// so back up again
					while ( !is_white_space(buf[i]) )
						i--;

					// now back up over intervening spaces
					while ( is_white_space(buf[i]) )
						i--;

					num_offsets_on_this_line = 2;
				}

				p_offset = &buf[i+1];			// get ptr to string section with offset in it

				if (buf[i] != '"')
					Error(LOCATION, "%s is corrupt", filename);		// now its an error
			}

			buf[i] = 0;

			// copy string into buf
			z = 0;
			for (i = 1; buf[i]; i++) {
				chr = buf[i];

				if (chr == '\\') {
					chr = buf[++i];

					if (chr == 'n')
						chr = '\n';
					else if (chr == 'r')
						chr = '\r';
				}

				buf[z++] = chr;
			}

			// null terminator on buf
			buf[z] = 0;
		}

		// write into Xstr_table (for strings.tbl) or Lcl_ext_str (for tstrings.tbl)
		if (Parsing_modular_table) {
			if ( external && (Lcl_ext_str[index] != NULL) ) {
				vm_free((void *) Lcl_ext_str[index]);
				Lcl_ext_str[index] = NULL;
			} else if ( !external && (Xstr_table[index].str != NULL) ) {
				vm_free((void *) Xstr_table[index].str);
				Xstr_table[index].str = NULL;
			}
		}

		if (external && (Lcl_ext_str[index] != NULL)) {
			Warning(LOCATION, "Tstrings table index %d used more than once", index);
		} else if (!external && (Xstr_table[index].str != NULL)) {
			Warning(LOCATION, "Strings table index %d used more than once", index);
		}

		if (external) {
			Lcl_ext_str[index] = vm_strdup(buf);
		} else {
			Xstr_table[index].str = vm_strdup(buf);
		}

		// the rest of this loop applies only to strings.tbl,
		// so we can move on to the next line if we're reading from tstrings.tbl
		if (external) {
			continue;
		}

		// read offset information, assume 0 if nonexistant
		if (p_offset != NULL) {
			if (sscanf(p_offset, "%d%d", &offset_lo, &offset_hi) < num_offsets_on_this_line) {
				// whatever is in the file ain't a proper offset
				Error(LOCATION, "%s is corrupt", filename);
			}
		}

		Xstr_table[index].offset_x = offset_lo;

		if (num_offsets_on_this_line == 2)
			Xstr_table[index].offset_x_hi = offset_hi;
		else
			Xstr_table[index].offset_x_hi = offset_lo;

		// clear out our vars
		p_offset = NULL;
		offset_lo = 0;
		offset_hi = 0;
	}
}
예제 #18
0
void parse_mod_table(const char *filename)
{
	int rval;
	// SCP_vector<SCP_string> lines;

	// open localization
	lcl_ext_open();

	if ((rval = setjmp(parse_abort)) != 0)
	{
		mprintf(("TABLES: Unable to parse '%s'!  Error code = %i.\n", (filename) ? filename : "<default game_settings.tbl>", rval));
		lcl_ext_close();
		return;
	}

	if (filename == NULL)
		read_file_text_from_array(defaults_get_file("game_settings.tbl"));
	else
		read_file_text(filename, CF_TYPE_TABLES);

	reset_parse();	

	// start parsing
	optional_string("#CAMPAIGN SETTINGS");

	if (optional_string("$Default Campaign File Name:")) {
		char temp[MAX_FILENAME_LEN];
		stuff_string(temp, F_NAME, MAX_FILENAME_LEN);

		// remove extension?
		if (drop_extension(temp)) {
			mprintf(("Game Settings Table: Removed extension on default campaign file name %s\n", temp));
		}

		// check length
		int maxlen = (MAX_FILENAME_LEN - 4);
		int len = strlen(temp);
		if (len > maxlen) {
			Warning(LOCATION, "Token too long: [%s].  Length = %i.  Max is %i.\n", temp, len, maxlen);
			temp[maxlen] = 0;
		}

		strcpy_s(Default_campaign_file_name, temp);
	}

	if (optional_string("#Ignored Campaign File Names")) {
		SCP_string campaign_name; 

		while (optional_string("$Campaign File Name:")) {
			stuff_string(campaign_name, F_NAME); 

			// remove extension?
			if (drop_extension(campaign_name)) {
				mprintf(("Game Settings Table: Removed extension on ignored campaign file name %s\n", campaign_name.c_str()));
			}

			Ignored_campaigns.push_back(campaign_name); 
		}
	}

	optional_string("#HUD SETTINGS");

	// how long should the game wait before displaying a directive?
	if (optional_string("$Directive Wait Time:")) {
		stuff_int(&Directive_wait_time);
	}

	if (optional_string("$Cutscene camera displays HUD:")) {
		stuff_boolean(&Cutscene_camera_displays_hud);
	}
	// compatibility
	if (optional_string("$Cutscene camera disables HUD:")) {
		mprintf(("Game Settings Table: \"$$Cutscene camera disables HUD\" is deprecated in favor of \"$Cutscene camera displays HUD\"\n"));
		bool temp;
		stuff_boolean(&temp);
		Cutscene_camera_displays_hud = !temp;
	}
	
	if (optional_string("$Full color head animations:")) {
		stuff_boolean(&Full_color_head_anis);
	}
	// compatibility
	if (optional_string("$Color head animations with hud colors:")) {
		mprintf(("Game Settings Table: \"$Color head animations with hud colors\" is deprecated in favor of \"$Full color head animations\"\n"));
		bool temp;
		stuff_boolean(&temp);
		Full_color_head_anis = !temp;
	}

	optional_string("#SEXP SETTINGS"); 

	if (optional_string("$Loop SEXPs Then Arguments:")) { 
		stuff_boolean(&True_loop_argument_sexps);
		if (True_loop_argument_sexps) {
			mprintf(("Game Settings Table: Using Reversed Loops For SEXP Arguments\n"));
		} else {
			mprintf(("Game Settings Table: Using Standard Loops For SEXP Arguments\n"));
		}
	}

	if (optional_string("$Use Alternate Chaining Behavior:")) {
		stuff_boolean(&Alternate_chaining_behavior);
		if (Alternate_chaining_behavior) {
			mprintf(("Game Settings Table: Using alternate event chaining behavior\n"));
		} else {
			mprintf(("Game Settings Table: Using standard event chaining behavior\n"));
		}
	}

	optional_string("#GRAPHICS SETTINGS");

	if (optional_string("$Enable External Shaders:")) {
		stuff_boolean(&Enable_external_shaders);
		if (Enable_external_shaders)
			mprintf(("Game Settings Table: External shaders are enabled\n"));
		else
			mprintf(("Game Settings Table: External shaders are DISABLED\n"));
	}

	if (optional_string("$Default Detail Level:")) {
		int detail_level;

		stuff_int(&detail_level);

		mprintf(("Game Settings Table: Setting default detail level to %i of %i-%i\n", detail_level, 0, NUM_DEFAULT_DETAIL_LEVELS-1));

		if (detail_level < 0 || detail_level > NUM_DEFAULT_DETAIL_LEVELS-1) {
			Warning(LOCATION, "Invalid detail level: %i, setting to %i\n", detail_level, Default_detail_level);
		} else {
			Default_detail_level = detail_level;
		}
	}
	
	optional_string("#NETWORK SETTINGS"); 

	if (optional_string("$FS2NetD port:")) {
		stuff_int(&FS2NetD_port);
		if (FS2NetD_port)
			mprintf(("Game Settings Table: FS2NetD connecting to port %i\n", FS2NetD_port));
	}

	optional_string("#OTHER SETTINGS"); 

	if (optional_string("$Fixed Turret Collisions:")) { 
		stuff_boolean(&Fixed_turret_collisions);
	}

	if (optional_string("$Damage Impacted Subsystem First:")) { 
		stuff_boolean(&Damage_impacted_subsystem_first);
	}

	if (optional_string("$Default ship select effect:")) {
		char effect[NAME_LENGTH];
		stuff_string(effect, F_NAME, NAME_LENGTH);
		if (!stricmp(effect, "FS2"))
			Default_ship_select_effect = 2;
		else if (!stricmp(effect, "FS1"))
			Default_ship_select_effect = 1;
		else if (!stricmp(effect, "off"))
			Default_ship_select_effect = 0;
	}

	if (optional_string("$Default weapon select effect:")) {
		char effect[NAME_LENGTH];
		stuff_string(effect, F_NAME, NAME_LENGTH);
		if (!stricmp(effect, "FS2"))
			Default_weapon_select_effect = 2;
		else if (!stricmp(effect, "FS1"))
			Default_weapon_select_effect = 1;
		else if (!stricmp(effect, "off"))
			Default_weapon_select_effect = 0;
	}

	if (optional_string("$Weapons inherit parent collision group:")) {
		stuff_boolean(&Weapons_inherit_parent_collision_group);
		if (Weapons_inherit_parent_collision_group)
			mprintf(("Game Settings Table: Weapons inherit parent collision group\n"));
	}

	if (optional_string("$Flight controls follow eyepoint orientation:")) {
		stuff_boolean(&Flight_controls_follow_eyepoint_orientation);
		if (Flight_controls_follow_eyepoint_orientation)
			mprintf(("Game Settings Table: Flight controls follow eyepoint orientation\n"));
	}

	required_string("#END");

	// close localization
	lcl_ext_close();
}
예제 #19
0
// initialize the xstr table
void lcl_xstr_init()
{
	char chr, buf[4096];
	char language_tag[512];	
	int i, z, index, rval;
	char *p_offset = NULL;
	int offset_lo = 0, offset_hi = 0;

	for (i=0; i<XSTR_SIZE; i++){
		Xstr_table[i].str = NULL;
	}

	if ((rval = setjmp(parse_abort)) != 0) {
		mprintf(("Error parsing 'strings.tbl'\nError code = %i.\n", rval));
	} else {
		// make sure localization is NOT running
		lcl_ext_close();

		read_file_text("strings.tbl");
		reset_parse();

		// move down to the proper section		
		memset(language_tag, 0, 512);
		strcpy(language_tag, "#");
		strcat(language_tag, Lcl_languages[Lcl_current_lang].lang_name);
		if(skip_to_string(language_tag) != 1){
			Error(LOCATION, NOX("Strings.tbl is corrupt"));
		}		

		// parse all the strings in this section of the table
		while (!check_for_string("#")) {
			int num_offsets_on_this_line = 0;

			stuff_int(&index);
			stuff_string(buf, F_NAME, NULL, 4096);
			i = strlen(buf);
			while (i--) {
				if (!isspace(buf[i])) {
					break;
				}
			}

			// trim unneccesary end of string
			if (i >= 0) {
				// Assert(buf[i] == '"');
				if (buf[i] != '"') {
					// probably an offset on this entry
					buf[i+1] = 0;						// drop down a null terminator (prolly unnecessary)
					while(!is_white_space(buf[i])) i--;	// back up over the potential offset
					while(is_white_space(buf[i])) i--;	// now back up over intervening spaces
					num_offsets_on_this_line = 1;
					if (buf[i] != '"') {
						// could have a 2nd offset value (one for 640, one for 1024)
						// so back up again
						while(!is_white_space(buf[i])) i--;	// back up over the 2nd offset
						while(is_white_space(buf[i])) i--;	// now back up over intervening spaces
						num_offsets_on_this_line = 2;
					}

					p_offset = &buf[i+1];			// get ptr to string section with offset in it
					if (buf[i] != '"') {
						Error(LOCATION, NOX("Strings.tbl is corrupt"));		// now its an error
					}
				}

				buf[i] = 0;
			}

			// copy string into buf
			z = 0;
			for (i=1; buf[i]; i++) {
				chr = buf[i];
				if (chr == '\\') {
					chr = buf[++i];
					if (chr == 'n') {
						chr = '\n';
					} else if (chr == 'r') {
						chr = '\r';
					}

				}

				buf[z++] = chr;
			}

			// null terminator on buf
			buf[z] = 0;

			// write into Xstr_table
			if (index >= 0 && index < XSTR_SIZE) {
				if (Xstr_table[index].str != NULL) {
					Warning(LOCATION, "Strings table index %d used more than once", index);
				}
				Xstr_table[index].str = strdup(buf);
			}

			// read offset information, assume 0 if nonexistant
			if (p_offset != NULL) {
				if (sscanf(p_offset, "%d%d", &offset_lo, &offset_hi) < num_offsets_on_this_line) {
					// whatever is in the file ain't a proper offset
					Error(LOCATION, NOX("Strings.tbl is corrupt"));
				}
			}
			Xstr_table[index].offset_x = offset_lo;
			if (num_offsets_on_this_line == 2) {
				Xstr_table[index].offset_x_hi = offset_hi;
			} else {
				Xstr_table[index].offset_x_hi = offset_lo;						
			}

			// clear out our vars
			p_offset = NULL;
			offset_lo = 0;
			offset_hi = 0;
			num_offsets_on_this_line = 0;
		}
	}

	Xstr_inited = 1;
}
void parse_species_tbl(const char *filename)
{
	int i, rval;
	char species_name[NAME_LENGTH];

	if ((rval = setjmp(parse_abort)) != 0)
	{
		mprintf(("TABLES: Unable to parse '%s'!  Error code = %i.\n", (filename) ? filename : NOX("<default species_defs.tbl>"), rval));
		return;
	}

	if (filename == NULL)
		read_file_text_from_array(defaults_get_file("species_defs.tbl"));
	else
		read_file_text(filename, CF_TYPE_TABLES);

	reset_parse();		


	// start parsing
	required_string("#SPECIES DEFS");

	// no longer required: counted automatically
	if (optional_string("$NumSpecies:"))
	{
		int temp;
		stuff_int(&temp);
	}

	// begin reading data
	while (required_string_either("#END","$Species_Name:"))
	{
		bool no_create = false;
		species_info *species, new_species;

		species = &new_species;

		// Start Species - Get its name
		required_string("$Species_Name:");
		stuff_string(species_name, F_NAME, NAME_LENGTH);

		if (optional_string("+nocreate"))
		{
			no_create = true;

			for (i = 0; i < (int)Species_info.size(); i++)
			{
				if (!stricmp(Species_info[i].species_name, species_name))
				{
					species = &Species_info[i];
					break;
				}
			}
		}
		else
		{
			strcpy_s(species->species_name, species_name);
		}

		// Goober5000 - IFF
		if (optional_string("$Default IFF:"))
		{
			bool iff_found = false;
			char temp_name[NAME_LENGTH];
			stuff_string(temp_name, F_NAME, NAME_LENGTH);

			// search for it in iffs
			for (int iLoop = 0; iLoop < Num_iffs; iLoop++)
			{
				if (!stricmp(Iff_info[iLoop].iff_name, temp_name))
				{
					species->default_iff = iLoop;
					iff_found = true;
				}
			}

			if (!iff_found)
			{
				species->default_iff = 0;
				Warning(LOCATION, "Species %s default IFF %s not found in iff_defs.tbl!  Defaulting to %s.\n", species->species_name, temp_name, Iff_info[species->default_iff].iff_name);
			}
		}
		else if (!no_create)
		{
			// we have no idea which it could be, so default to 0
			species->default_iff = 0;

			// let them know
			Warning(LOCATION, "$Default IFF not specified for species %s in species_defs.tbl!  Defaulting to %s.\n", species->species_name, Iff_info[species->default_iff].iff_name);
		}

		// Goober5000 - FRED color
		if (optional_string("$FRED Color:") || optional_string("$FRED Colour:"))
		{
			stuff_int_list(species->fred_color.a1d, 3, RAW_INTEGER_TYPE);
		}
		else if (!no_create)
		{
			// set defaults to Volition's originals
			if (!stricmp(species->species_name, "Terran"))
			{
				species->fred_color.rgb.r = 0;
				species->fred_color.rgb.g = 0;
				species->fred_color.rgb.b = 192;
			}
			else if (!stricmp(species->species_name, "Vasudan"))
			{
				species->fred_color.rgb.r = 0;
				species->fred_color.rgb.g = 128;
				species->fred_color.rgb.b = 0;
			}
			else if (!stricmp(species->species_name, "Shivan"))
			{
				species->fred_color.rgb.r = 192;
				species->fred_color.rgb.g = 0;
				species->fred_color.rgb.b = 0;
			}
			else if (!stricmp(species->species_name, "Ancients") || !stricmp(species->species_name, "Ancient"))
			{
				species->fred_color.rgb.r = 192;
				species->fred_color.rgb.g = 0;
				species->fred_color.rgb.b = 192;
			}
			else
			{
				species->fred_color.rgb.r = 0;
				species->fred_color.rgb.g = 0;
				species->fred_color.rgb.b = 0;
			}

			// let them know
			Warning(LOCATION, "$FRED Color not specified for species %s in species_defs.tbl!  Defaulting to (%d, %d, %d).\n", species->species_name, species->fred_color.rgb.r, species->fred_color.rgb.g, species->fred_color.rgb.b);
		}

		// stuff
		optional_string("$MiscAnims:");

		// Get its Debris Texture
		if ((!no_create && required_string("+Debris_Texture:")) || optional_string("+Debris_Texture:"))
		{
			generic_bitmap_init(&species->debris_texture, NULL);
			stuff_string(species->debris_texture.filename, F_NAME, MAX_FILENAME_LEN);
		}


		// Shield Hit Animation
        if (optional_string("+Shield_Hit_ani:")) // Shouldn't be required -- LPine
		{
			generic_anim_init(&species->shield_anim, NULL);
			stuff_string(species->shield_anim.filename, F_NAME, MAX_FILENAME_LEN);
		}
        else if (!no_create)
        {
            species->shield_anim.filename[0] = '\0';
            species->shield_anim.first_frame = -1; // Landmine to trip up anyone who does end up using this
        }


		// Thruster Anims
		parse_thrust_anims(species, no_create);

		// Thruster Glow Anims
		parse_thrust_glows(species, no_create);


		// Goober5000 - AWACS multiplier
		if (optional_string("$AwacsMultiplier:"))
		{
			stuff_float(&species->awacs_multiplier);
		}
		else if (!no_create)
		{
			// set defaults to Volition's originals
			if (!stricmp(species->species_name, "Vasudan"))
				species->awacs_multiplier = 1.25f;
			else if (!stricmp(species->species_name, "Shivan"))
				species->awacs_multiplier = 1.50f;
			else
				species->awacs_multiplier = 1.0f;

			// let them know
			Warning(LOCATION, "$AwacsMultiplier not specified for species %s in species_defs.tbl!  Defaulting to %.2d.\n", species->species_name, species->awacs_multiplier);
		}

		// Goober5000 - countermeasure type
		// (we won't be able to resolve it until after we've parsed the weapons table)
		if (optional_string("$Countermeasure type:"))
			stuff_string(species->cmeasure_name, F_NAME, NAME_LENGTH);

		// don't add new entry if this is just a modified one
		if ( !no_create )
			Species_info.push_back( new_species );
	}
	
	required_string("#END");

	// add tbl/tbm to multiplayer validation list
	extern void fs2netd_add_table_validation(const char *tblname);
	fs2netd_add_table_validation(filename);
}
예제 #21
0
void parse_sound_environments()
{
	char name[65] = { '\0' };
	char template_name[65] = { '\0' };
	EFXREVERBPROPERTIES *props;

	while (required_string_either("#Sound Environments End", "$Name:"))
	{
		required_string("$Name:");
		stuff_string(name, F_NAME, sizeof(name)-1);

		if (optional_string("$Template:"))
		{
			stuff_string(template_name, F_NAME, sizeof(template_name)-1);
		}
		else
		{
			template_name[0] = '\0';
		}

		ds_eax_get_prop(&props, name, template_name);

		if (optional_string("+Density:"))
		{
			stuff_float(&props->flDensity);
			CLAMP(props->flDensity, 0.0f, 1.0f);
		}

		if (optional_string("+Diffusion:"))
		{
			stuff_float(&props->flDiffusion);
			CLAMP(props->flDiffusion, 0.0f, 1.0f);
		}

		if (optional_string("+Gain:"))
		{
			stuff_float(&props->flGain);
			CLAMP(props->flGain, 0.0f, 1.0f);
		}

		if (optional_string("+Gain HF:"))
		{
			stuff_float(&props->flGainHF);
			CLAMP(props->flGainHF, 0.0f, 1.0f);
		}

		if (optional_string("+Gain LF:"))
		{
			stuff_float(&props->flGainLF);
			CLAMP(props->flGainLF, 0.0f, 1.0f);
		}

		if (optional_string("+Decay Time:"))
		{
			stuff_float(&props->flDecayTime);
			CLAMP(props->flDecayTime, 0.01f, 20.0f);
		}

		if (optional_string("+Decay HF Ratio:"))
		{
			stuff_float(&props->flDecayHFRatio);
			CLAMP(props->flDecayHFRatio, 0.1f, 20.0f);
		}

		if (optional_string("+Decay LF Ratio:"))
		{
			stuff_float(&props->flDecayLFRatio);
			CLAMP(props->flDecayLFRatio, 0.1f, 20.0f);
		}

		if (optional_string("+Reflections Gain:"))
		{
			stuff_float(&props->flReflectionsGain);
			CLAMP(props->flReflectionsGain, 0.0f, 3.16f);
		}

		if (optional_string("+Reflections Delay:"))
		{
			stuff_float(&props->flReflectionsDelay);
			CLAMP(props->flReflectionsDelay, 0.0f, 0.3f);
		}

		if (optional_string("+Reflections Pan:"))
		{
			stuff_float_list(props->flReflectionsPan, 3);
			CLAMP(props->flReflectionsPan[0], 0.0f, 1.0f);
			CLAMP(props->flReflectionsPan[1], 0.0f, 1.0f);
			CLAMP(props->flReflectionsPan[2], 0.0f, 1.0f);
		}

		if (optional_string("+Late Reverb Gain:"))
		{
			stuff_float(&props->flLateReverbGain);
			CLAMP(props->flLateReverbGain, 0.0f, 10.0f);
		}

		if (optional_string("+Late Reverb Delay:"))
		{
			stuff_float(&props->flLateReverbDelay);
			CLAMP(props->flLateReverbDelay, 0.0f, 0.1f);
		}

		if (optional_string("+Late Reverb Pan:"))
		{
			stuff_float_list(props->flLateReverbPan, 3);
			CLAMP(props->flLateReverbPan[0], 0.0f, 1.0f);
			CLAMP(props->flLateReverbPan[1], 0.0f, 1.0f);
			CLAMP(props->flLateReverbPan[2], 0.0f, 1.0f);
		}

		if (optional_string("+Echo Time:"))
		{
			stuff_float(&props->flEchoTime);
			CLAMP(props->flEchoTime, 0.075f, 0.25f);
		}

		if (optional_string("+Echo Depth:"))
		{
			stuff_float(&props->flEchoDepth);
			CLAMP(props->flEchoDepth, 0.0f, 1.0f);
		}

		if (optional_string("+Modulation Time:"))
		{
			stuff_float(&props->flModulationTime);
			CLAMP(props->flModulationTime, 0.004f, 4.0f);
		}

		if (optional_string("+Modulation Depth:"))
		{
			stuff_float(&props->flModulationDepth);
			CLAMP(props->flModulationDepth, 0.0f, 1.0f);
		}

		if (optional_string("+HF Reference:"))
		{
			stuff_float(&props->flHFReference);
			CLAMP(props->flHFReference, 1000.0f, 20000.0f);
		}

		if (optional_string("+LF Reference:"))
		{
			stuff_float(&props->flLFReference);
			CLAMP(props->flLFReference, 20.0f, 1000.0f);
		}

		if (optional_string("+Room Rolloff Factor:"))
		{
			stuff_float(&props->flRoomRolloffFactor);
			CLAMP(props->flRoomRolloffFactor, 0.0f, 10.0f);
		}

		if (optional_string("+Air Absorption Gain HF:"))
		{
			stuff_float(&props->flAirAbsorptionGainHF);
			CLAMP(props->flAirAbsorptionGainHF, 0.892f, 1.0f);
		}

		if (optional_string("+Decay HF Limit:"))
		{
			stuff_int(&props->iDecayHFLimit);
			CLAMP(props->iDecayHFLimit, 0, 1);
		}
	}

	required_string("#Sound Environments End");
}
예제 #22
0
void parse_gamesnd_new(game_snd* gs, bool no_create)
{
	char name[MAX_FILENAME_LEN];
	// New extended format found
	stuff_string(name, F_NAME, MAX_FILENAME_LEN);

	if (!stricmp(name, NOX("empty")))
	{
		gs->filename[0] = 0;
		return;
	}

	// If the name _doesn't_ match <same> put it into gs->filename;
	if (stricmp(name, "<same>"))
	{
		strcpy_s(gs->filename, name);
	}
	else if (!no_create)
	{
		// Throw an error if <same> was specified but we are creating a new entry
		error_display(1, "'<same>' is only allowed if +nocreate was specified!");
		return;
	}

	if (required_string_no_create("+Preload:", no_create))
	{
		stuff_boolean(&gs->preload);
	}

	if (required_string_no_create("+Volume:", no_create))
	{
		stuff_float(&gs->default_volume);
	}

	if (optional_string("+3D Sound:"))
	{
		gs->flags |= GAME_SND_USE_DS3D;
		required_string("+Attenuation start:");

		stuff_int(&gs->min);

		required_string("+Attenuation end:");

		stuff_int(&gs->max);
	}
	else
	{
		gs->min = 0;
		gs->max = 0;
	}

	// jg18 - enhanced sound parameters
	if (optional_string("+Priority:"))
	{
		SCP_string priority_string;
		stuff_string(priority_string, F_NAME);
		EnhancedSoundPriority priority = convert_to_enhanced_priority(priority_string.c_str());
		if (priority != SND_ENHANCED_PRIORITY_INVALID)
		{
			gs->enhanced_sound_data.priority= priority;
		}
		// else case not needed since conversion function displays message on error
	}

	if (optional_string("+Limit:"))
	{
		int temp_limit;
		stuff_int(&temp_limit);

		if ((temp_limit > 0) && (static_cast<uint>(temp_limit) <= SND_ENHANCED_MAX_LIMIT))
		{
			gs->enhanced_sound_data.limit = (unsigned int)temp_limit;
		}
		else
		{
			error_display(1, "Invalid enhanced sound limit: %d\n", temp_limit);
		}
	}
}
예제 #23
0
void credits_parse_table(const char* filename)
{	
	try
	{
		read_file_text(filename, CF_TYPE_TABLES);
		reset_parse();

		// any metadata?
		if (optional_string("$Music:"))
		{
			stuff_string(Credits_music_name, F_NAME, NAME_LENGTH);
		}
		if (optional_string("$Number of Images:"))
		{
			int temp;
			stuff_int(&temp);
			if (temp > 0)
				Credits_num_images = temp;
		}
		if (optional_string("$Start Image Index:"))
		{
			stuff_int(&Credits_artwork_index);

			// bounds check
			if (Credits_artwork_index < 0)
			{
				Credits_artwork_index = 0;
			}
			else if (Credits_artwork_index >= Credits_num_images)
			{
				Credits_artwork_index = Credits_num_images - 1;
			}
		}
		if (optional_string("$Text scroll rate:"))
		{
			stuff_float(&Credits_scroll_rate);
			if (Credits_scroll_rate < 0.01f)
				Credits_scroll_rate = 0.01f;
		}
		if (optional_string("$Artworks display time:"))
		{
			stuff_float(&Credits_artwork_display_time);
			if (Credits_artwork_display_time < 0.01f)
				Credits_artwork_display_time = 0.01f;
		}
		if (optional_string("$Artworks fade time:"))
		{
			stuff_float(&Credits_artwork_fade_time);
			if (Credits_artwork_fade_time < 0.01f)
				Credits_artwork_fade_time = 0.01f;
		}
		if (optional_string("$SCP Credits position:"))
		{
			char mode[NAME_LENGTH];

			stuff_string(mode, F_NAME, NAME_LENGTH);

			if (!stricmp(mode, "Start"))
				SCP_credits_position = START;
			else if (!stricmp(mode, "End"))
				SCP_credits_position = END;
			else
				Warning(LOCATION, "Unknown credits position mode \"%s\".", mode);
		}

		ignore_white_space();

		SCP_string credits_text;
		SCP_string line;

		SCP_vector<int> charNum;
		SCP_vector<const char*> lines;
		int numLines = -1;

		bool first_run = true;
		while (!check_for_string_raw("#end"))
		{
			// Read in a line of text			
			stuff_string_line(line);

			// This is a bit odd but it means if a total conversion uses different credits the 
			// Volition credit won't happen
			// Also don't append the default credits anymore when there was already a parsed table
			if (first_run && !Credits_parsed && !line.compare(mod_check))
			{
				credits_text.append(unmodified_credits);
			}

			first_run = false;

			if (line.empty())
			{
				// If the line is empty then just append a newline, don't bother with splitting it first
				credits_text.append("\n");
			}
			else
			{
				// split_str doesn't take care of this.
				charNum.clear();

				// Split the string into multiple lines if it's too long
				numLines = split_str(line.c_str(), Credits_text_coords[gr_screen.res][2], charNum, lines, -1);

				// Make sure that we have valid data
				Assertion(lines.size() == (size_t)numLines, "split_str reported %d lines but vector contains " SIZE_T_ARG " entries!", numLines, lines.size());

				Assertion(lines.size() <= charNum.size(),
					"Something has gone wrong while splitting strings. Got " SIZE_T_ARG " lines but only " SIZE_T_ARG " chacter lengths.",
					lines.size(), charNum.size());

				// Now add all splitted lines to the credit text and append a newline to the end
				for (int i = 0; i < numLines; i++)
				{
					credits_text.append(SCP_string(lines[i], charNum[i]));
					credits_text.append("\n");
				}
			}
		}

		Credit_text_parts.push_back(credits_text);

		Credits_parsed = true;
	}
	catch (const parse::ParseException& e)
	{
		mprintf(("TABLES: Unable to parse '%s'!  Error message = %s.\n", filename, e.what()));
		return;
	}
}
static bool opengl_post_init_table()
{
	bool warned = false;

	try
	{
		if (cf_exists_full("post_processing.tbl", CF_TYPE_TABLES))
			read_file_text("post_processing.tbl", CF_TYPE_TABLES);
		else
			read_file_text_from_default(defaults_get_file("post_processing.tbl"));

		reset_parse();


		if (optional_string("#Effects")) {
			while (!required_string_one_of(3, "$Name:", "#Ship Effects", "#End")) {
				char tbuf[NAME_LENGTH + 1] = { 0 };
				post_effect_t eff;

				required_string("$Name:");
				stuff_string(tbuf, F_NAME, NAME_LENGTH);
				eff.name = tbuf;

				required_string("$Uniform:");
				stuff_string(tbuf, F_NAME, NAME_LENGTH);
				eff.uniform_name = tbuf;

				required_string("$Define:");
				stuff_string(tbuf, F_NAME, NAME_LENGTH);
				eff.define_name = tbuf;

				required_string("$AlwaysOn:");
				stuff_boolean(&eff.always_on);

				required_string("$Default:");
				stuff_float(&eff.default_intensity);
				eff.intensity = eff.default_intensity;

				required_string("$Div:");
				stuff_float(&eff.div);

				required_string("$Add:");
				stuff_float(&eff.add);

				// Post_effects index is used for flag checks, so we can't have more than 32
				if (Post_effects.size() < 32) {
					Post_effects.push_back(eff);
				}
				else if (!warned) {
					mprintf(("WARNING: post_processing.tbl can only have a max of 32 effects! Ignoring extra...\n"));
					warned = true;
				}
			}
		}

		//Built-in per-ship effects
		ship_effect se1;
		strcpy_s(se1.name, "FS1 Ship select");
		se1.shader_effect = 0;
		se1.disables_rendering = false;
		se1.invert_timer = false;
		Ship_effects.push_back(se1);

		if (optional_string("#Ship Effects")) {
			while (!required_string_one_of(3, "$Name:", "#Light Shafts", "#End")) {
				ship_effect se;
				char tbuf[NAME_LENGTH] = { 0 };

				required_string("$Name:");
				stuff_string(tbuf, F_NAME, NAME_LENGTH);
				strcpy_s(se.name, tbuf);

				required_string("$Shader Effect:");
				stuff_int(&se.shader_effect);

				required_string("$Disables Rendering:");
				stuff_boolean(&se.disables_rendering);

				required_string("$Invert timer:");
				stuff_boolean(&se.invert_timer);

				Ship_effects.push_back(se);
			}
		}

		if (optional_string("#Light Shafts")) {
			required_string("$AlwaysOn:");
			stuff_boolean(&ls_on);
			required_string("$Density:");
			stuff_float(&ls_density);
			required_string("$Falloff:");
			stuff_float(&ls_falloff);
			required_string("$Weight:");
			stuff_float(&ls_weight);
			required_string("$Intensity:");
			stuff_float(&ls_intensity);
			required_string("$Sample Number:");
			stuff_int(&ls_samplenum);

			ls_cpintensity = ls_weight;
			for (int i = 1; i < ls_samplenum; i++)
				ls_cpintensity += ls_weight * pow(ls_falloff, i);
			ls_cpintensity *= ls_intensity;
		}

		required_string("#End");

		return true;
	}
	catch (const parse::ParseException& e)
	{
		mprintf(("Unable to parse 'post_processing.tbl'!  Error message = %s.\n", e.what()));
		return false;
	}
}
예제 #25
0
/**
 * Parse the table
 */
void iff_init()
{
	char traitor_name[NAME_LENGTH];
	char attack_names[MAX_IFFS][MAX_IFFS][NAME_LENGTH];
	struct {
		char iff_name[NAME_LENGTH];
		int color_index;
	} observed_color_table[MAX_IFFS][MAX_IFFS];

	int num_attack_names[MAX_IFFS];
	int num_observed_colors[MAX_IFFS];
	int i, j, k;
	int string_idx;

	try
	{
		// Goober5000 - if table doesn't exist, use the default table
		if (cf_exists_full("iff_defs.tbl", CF_TYPE_TABLES))
			read_file_text("iff_defs.tbl", CF_TYPE_TABLES);
		else
			read_file_text_from_array(defaults_get_file("iff_defs.tbl"));

		reset_parse();

		// parse the table --------------------------------------------------------

		required_string("#IFFs");

		// get the traitor
		required_string("$Traitor IFF:");
		stuff_string(traitor_name, F_NAME, NAME_LENGTH);

		int rgb[3];

		// check if alternate colours are wanted to be used for these
		// Marks various stuff... like asteroids
		if ((optional_string("$Selection Color:")) || (optional_string("$Selection Colour:")))
		{
			stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
			iff_init_color(rgb[0], rgb[1], rgb[2]);
		}
		else
			iff_init_color(0xff, 0xff, 0xff);

		// Marks the ship currently saying something
		if ((optional_string("$Message Color:")) || (optional_string("$Message Colour:")))
		{
			stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
			iff_init_color(rgb[0], rgb[1], rgb[2]);
		}
		else
			iff_init_color(0x7f, 0x7f, 0x7f);

		// Marks the tagged ships
		if ((optional_string("$Tagged Color:")) || (optional_string("$Tagged Colour:")))
		{
			stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
			iff_init_color(rgb[0], rgb[1], rgb[2]);
		}
		else
			iff_init_color(0xff, 0xff, 0x00);

		// init radar blips colour table
		int a_bright, a_dim;
		bool alternate_blip_color = false;
		for (i = 0; i < 5; i++)
		{
			for (j = 0; j < 2; j++)
			{
				for (k = 0; k < 3; k++)
				{
					radar_iff_color[i][j][k] = -1;
				}
			}
		}

		// if the bright/dim scaling is wanted to be changed
		if (optional_string("$Dimmed IFF brightness:"))
		{
			int dim_iff_brightness;
			stuff_int(&dim_iff_brightness);
			Assert(dim_iff_brightness >= 0 && dim_iff_brightness <= HUD_COLOR_ALPHA_MAX);
			*iff_color_brightness = dim_iff_brightness;
		}
		else
			*iff_color_brightness = 4;

		// alternate = use same method as with ship blips
		// retail = use 1/2 intensities
		if (optional_string("$Use Alternate Blip Coloring:") || optional_string("$Use Alternate Blip Colouring:"))
		{
			stuff_boolean(&alternate_blip_color);
		}

		// Parse blip colours, their order is hardcoded.
		if ((optional_string("$Missile Blip Color:")) || (optional_string("$Missile Blip Colour:")))
		{
			stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
			for (i = 0; i < 3; i++)
			{
				Assert(rgb[i] >= 0 && rgb[i] <= 255);
				radar_iff_color[0][1][i] = rgb[i];
				radar_iff_color[0][0][i] = rgb[i] / 2;
			}
		}

		if ((optional_string("$Navbuoy Blip Color:")) || (optional_string("$Navbuoy Blip Colour:")))
		{
			stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
			for (i = 0; i < 3; i++)
			{
				Assert(rgb[i] >= 0 && rgb[i] <= 255);
				radar_iff_color[1][1][i] = rgb[i];
				radar_iff_color[1][0][i] = rgb[i] / 2;
			}
		}

		if ((optional_string("$Warping Blip Color:")) || (optional_string("$Warping Blip Colour:")))
		{
			stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
			for (i = 0; i < 3; i++)
			{
				Assert(rgb[i] >= 0 && rgb[i] <= 255);
				radar_iff_color[2][1][i] = rgb[i];
				radar_iff_color[2][0][i] = rgb[i] / 2;
			}
		}

		if ((optional_string("$Node Blip Color:")) || (optional_string("$Node Blip Colour:")))
		{
			stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
			for (i = 0; i < 3; i++)
			{
				Assert(rgb[i] >= 0 && rgb[i] <= 255);
				radar_iff_color[3][1][i] = rgb[i];
				radar_iff_color[3][0][i] = rgb[i] / 2;
			}
		}

		if ((optional_string("$Tagged Blip Color:")) || (optional_string("$Tagged Blip Colour:")))
		{
			stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
			for (i = 0; i < 3; i++)
			{
				Assert(rgb[i] >= 0 && rgb[i] <= 255);
				radar_iff_color[4][1][i] = rgb[i];
				radar_iff_color[4][0][i] = rgb[i] / 2;
			}
		}

		if (alternate_blip_color == true)
		{
			a_bright = iff_get_alpha_value(true);
			a_dim = iff_get_alpha_value(false);
			for (i = 0; i < 5; i++)
			{
				if (radar_iff_color[i][0][0] >= 0)
				{
					for (j = 0; j < 3; j++)
					{
						radar_iff_color[i][0][j] = radar_iff_color[i][1][j];
					}

					radar_iff_color[i][1][3] = a_bright;
					radar_iff_color[i][0][3] = a_dim;
				}
			}
		}
		else
		{
			for (i = 0; i < 5; i++)
			{
				if (radar_iff_color[i][0][0] >= 0)
				{
					radar_iff_color[i][0][3] = 255;
					radar_iff_color[i][1][3] = 255;
				}
			}
		}

		if (optional_string("$Radar Target ID Flags:")) {
			parse_string_flag_list((int*)&radar_target_id_flags, rti_flags, Num_rti_flags);
			if (optional_string("+reset"))
				radar_target_id_flags = 0;
		}

		// begin reading data
		Num_iffs = 0;
		while (required_string_either("#End", "$IFF Name:"))
		{
			iff_info *iff;
			int cur_iff;

			// make sure we're under the limit
			if (Num_iffs >= MAX_IFFS)
			{
				Warning(LOCATION, "Too many iffs in iffs_defs.tbl!  Max is %d.\n", MAX_IFFS);
				skip_to_start_of_string("#End", NULL);
				break;
			}

			// add new IFF
			iff = &Iff_info[Num_iffs];
			cur_iff = Num_iffs;
			Num_iffs++;


			// get required IFF info ----------------------------------------------

			// get the iff name
			required_string("$IFF Name:");
			stuff_string(iff->iff_name, F_NAME, NAME_LENGTH);

			// get the iff color
			if (check_for_string("$Colour:"))
				required_string("$Colour:");
			else
				required_string("$Color:");
			stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
			iff->color_index = iff_init_color(rgb[0], rgb[1], rgb[2]);


			// get relationships between IFFs -------------------------------------

			// get the list of iffs attacked
			if (optional_string("$Attacks:"))
				num_attack_names[cur_iff] = stuff_string_list(attack_names[cur_iff], MAX_IFFS);
			else
				num_attack_names[cur_iff] = 0;

			// get the list of observed colors
			num_observed_colors[cur_iff] = 0;
			while (optional_string("+Sees"))
			{
				// get iff observed
				stuff_string_until(observed_color_table[cur_iff][num_observed_colors[cur_iff]].iff_name, "As:", NAME_LENGTH);
				required_string("As:");

				// get color observed
				stuff_int_list(rgb, 3, RAW_INTEGER_TYPE);
				observed_color_table[cur_iff][num_observed_colors[cur_iff]].color_index = iff_init_color(rgb[0], rgb[1], rgb[2]);

				// increment
				num_observed_colors[cur_iff]++;
			}


			// get flags ----------------------------------------------------------

			// get iff flags
			iff->flags = 0;
			if (optional_string("$Flags:"))
			{
				char flag_strings[MAX_IFF_FLAGS][NAME_LENGTH];

				int num_strings = stuff_string_list(flag_strings, MAX_IFF_FLAGS);
				for (string_idx = 0; string_idx < num_strings; string_idx++)
				{
					if (!stricmp(NOX("support allowed"), flag_strings[string_idx]))
						iff->flags |= IFFF_SUPPORT_ALLOWED;
					else if (!stricmp(NOX("exempt from all teams at war"), flag_strings[string_idx]))
						iff->flags |= IFFF_EXEMPT_FROM_ALL_TEAMS_AT_WAR;
					else if (!stricmp(NOX("orders hidden"), flag_strings[string_idx]))
						iff->flags |= IFFF_ORDERS_HIDDEN;
					else if (!stricmp(NOX("orders shown"), flag_strings[string_idx]))
						iff->flags |= IFFF_ORDERS_SHOWN;
					else if (!stricmp(NOX("wing name hidden"), flag_strings[string_idx]))
						iff->flags |= IFFF_WING_NAME_HIDDEN;
					else
						Warning(LOCATION, "Bogus string in iff flags: %s\n", flag_strings[string_idx]);
				}
			}

			// get default ship flags
			iff->default_parse_flags = 0;
			if (optional_string("$Default Ship Flags:"))
			{
				i = 0;
				j = 0;
				char flag_strings[MAX_PARSE_OBJECT_FLAGS][NAME_LENGTH];
				int num_strings = stuff_string_list(flag_strings, MAX_PARSE_OBJECT_FLAGS);
				for (i = 0; i < num_strings; i++)
				{
					for (j = 0; j < MAX_PARSE_OBJECT_FLAGS; j++)
					{
						if (!stricmp(flag_strings[i], Parse_object_flags[j]))
						{
							iff->default_parse_flags |= (1 << j);
							break;
						}
					}
				}

				if (j == MAX_PARSE_OBJECT_FLAGS)
					Warning(LOCATION, "Bogus string in iff default ship flags: %s\n", flag_strings[i]);
			}

			// again
			iff->default_parse_flags2 = 0;
			if (optional_string("$Default Ship Flags2:"))
			{
				i = 0;
				j = 0;
				char flag_strings[MAX_PARSE_OBJECT_FLAGS_2][NAME_LENGTH];
				int num_strings = stuff_string_list(flag_strings, MAX_PARSE_OBJECT_FLAGS_2);
				for (i = 0; i < num_strings; i++)
				{
					for (j = 0; j < MAX_PARSE_OBJECT_FLAGS_2; j++)
					{
						if (!stricmp(flag_strings[i], Parse_object_flags_2[j]))
						{
							iff->default_parse_flags2 |= (1 << j);
							break;
						}
					}
				}

				if (j == MAX_PARSE_OBJECT_FLAGS_2)
					Warning(LOCATION, "Bogus string in iff default ship flags2: %s\n", flag_strings[i]);
			}

			// this is cleared between each level but let's just set it here for thoroughness
			iff->ai_rearm_timestamp = timestamp(-1);
		}

		required_string("#End");


		// now resolve the relationships ------------------------------------------

		// first get the traitor
		Iff_traitor = iff_lookup(traitor_name);
		if (Iff_traitor < 0)
		{
			Iff_traitor = 0;
			Warning(LOCATION, "Traitor IFF %s not found in iff_defs.tbl!  Defaulting to %s.\n", traitor_name, Iff_info[Iff_traitor].iff_name);
		}

		// next get the attackees and colors
		for (int cur_iff = 0; cur_iff < Num_iffs; cur_iff++)
		{
			iff_info *iff = &Iff_info[cur_iff];

			// clear the iffs to be attacked
			iff->attackee_bitmask = 0;
			iff->attackee_bitmask_all_teams_at_war = 0;

			// clear the observed colors
			for (j = 0; j < MAX_IFFS; j++)
				iff->observed_color_index[j] = -1;

			// resolve the list names
			for (int list_index = 0; list_index < MAX_IFFS; list_index++)
			{
				// are we within the number of attackees listed?
				if (list_index < num_attack_names[cur_iff])
				{
					// find out who
					int target_iff = iff_lookup(attack_names[cur_iff][list_index]);

					// valid?
					if (target_iff >= 0)
						iff->attackee_bitmask |= iff_get_mask(target_iff);
					else
						Warning(LOCATION, "Attack target IFF %s not found for IFF %s in iff_defs.tbl!\n", attack_names[cur_iff][list_index], iff->iff_name);
				}

				// are we within the number of colors listed?
				if (list_index < num_observed_colors[cur_iff])
				{
					// find out who
					int target_iff = iff_lookup(observed_color_table[cur_iff][list_index].iff_name);

					// valid?
					if (target_iff >= 0)
						iff->observed_color_index[target_iff] = observed_color_table[cur_iff][list_index].color_index;
					else
						Warning(LOCATION, "Observed color IFF %s not found for IFF %s in iff_defs.tbl!\n", observed_color_table[cur_iff][list_index].iff_name, iff->iff_name);
				}
			}

			// resolve the all teams at war relationships
			if (iff->flags & IFFF_EXEMPT_FROM_ALL_TEAMS_AT_WAR)
			{
				// exempt, so use standard attacks
				iff->attackee_bitmask_all_teams_at_war = iff->attackee_bitmask;
			}
			else
			{
				// nonexempt, so build bitmask of all other nonexempt teams
				for (int other_iff = 0; other_iff < Num_iffs; other_iff++)
				{
					// skip myself (unless I attack myself normally)
					if ((other_iff == cur_iff) && !iff_x_attacks_y(cur_iff, cur_iff))
						continue;

					// skip anyone exempt
					if (Iff_info[other_iff].flags & IFFF_EXEMPT_FROM_ALL_TEAMS_AT_WAR)
						continue;

					// add everyone else
					iff->attackee_bitmask_all_teams_at_war |= iff_get_mask(other_iff);
				}
			}
		}

		// add tbl/tbm to multiplayer validation list
		extern void fs2netd_add_table_validation(const char *tblname);
		fs2netd_add_table_validation("iff_defs.tbl");
	}
	catch (const parse::ParseException& e)
	{
		mprintf(("TABLES: Unable to parse '%s'!  Error message = %s.\n", "iff_defs.tbl", e.what()));
		return;
	}
}
예제 #26
0
void parse_medal_tbl()
{
	int rval, i;
	int num_badges = 0;

	// open localization
	lcl_ext_open();

	if ((rval = setjmp(parse_abort)) != 0)
	{
		mprintf(("TABLES: Unable to parse '%s'!  Error code = %i.\n", "medals.tbl", rval));
		lcl_ext_close();
		return;
	}

	read_file_text("medals.tbl", CF_TYPE_TABLES);
	reset_parse();

	// parse in all the rank names
	Num_medals = 0;
	required_string("#Medals");
	while (required_string_either("#End", "$Name:"))
	{
		medal_stuff temp_medal;

		required_string("$Name:");
		stuff_string(temp_medal.name, F_NAME, NAME_LENGTH);

		required_string("$Bitmap:");
		stuff_string(temp_medal.bitmap, F_NAME, MAX_FILENAME_LEN);

		required_string("$Num mods:");
		stuff_int(&temp_medal.num_versions);

		// some medals are based on kill counts.  When string +Num Kills: is present, we know that
		// this medal is a badge and should be treated specially
		if (optional_string("+Num Kills:"))
		{
			char buf[MULTITEXT_LENGTH];

			stuff_int(&temp_medal.kills_needed);

			if (optional_string("$Wavefile 1:"))
				stuff_string(temp_medal.voice_base, F_NAME, MAX_FILENAME_LEN);
			if (optional_string("$Wavefile 2:"))
				stuff_string(temp_medal.voice_base, F_NAME, MAX_FILENAME_LEN);
			//stuff_string(Badge_info[bi].wave2, F_NAME, NULL, MAX_FILENAME_LEN);

			if (optional_string("$Wavefile Base:"))
				stuff_string(temp_medal.voice_base, F_NAME, MAX_FILENAME_LEN);

			//required_string("$Wavefile 2:");
			//stuff_string(Badge_info[bi].wave2, F_NAME, NULL, MAX_FILENAME_LEN);

			required_string("$Promotion Text:");
			stuff_string(buf, F_MULTITEXT, sizeof(buf));
			temp_medal.promotion_text = vm_strdup(buf);

			// since badges (ace ranks) are handled a little differently we need to know
			// which we are in the list of badges.
			temp_medal.badge_num = num_badges++;
		}

		Medals.push_back(temp_medal);
	}

	required_string("#End");

	Num_medals = Medals.size();
	Assert(Num_medals == MAX_MEDALS);

	// be sure that the badges kill numbers show up in order
	//WMC - I don't think this is needed anymore due to my changes to post-mission functions
	//but I'm keeping it here to be sure.
	int prev_badge_kills = 0;
	for (i = 0; i < Num_medals; i++)
	{
		if (Medals[i].kills_needed < prev_badge_kills && Medals[i].kills_needed != 0)
			Error(LOCATION,
				"Badges must appear sorted by lowest kill # first in medals.tbl\nFind Allender for most information.");

		if (Medals[i].kills_needed > 0)
			prev_badge_kills = Medals[i].kills_needed;
	}

	// close localization
	lcl_ext_close();
}
// parses help.tbl and populates help_overlaylist[]
void parse_helptbl(const char *filename)
{
	int overlay_id, currcount, vtxcount;
	char name[HELP_MAX_NAME_LENGTH];
	char buf[HELP_MAX_STRING_LENGTH + 1];
	int i, j, rval;

	SCP_vector<help_pline> pline_temp;
	help_pline pline_temp2;
	SCP_vector<help_text> text_temp;
	help_text text_temp2;
	SCP_vector<help_right_bracket> rbracket_temp;
	help_right_bracket rbracket_temp2;
	SCP_vector<help_left_bracket> lbracket_temp;
	help_left_bracket lbracket_temp2;
	vec3d vec3d_temp;
	
	if ((rval = setjmp(parse_abort)) != 0) {
		mprintf(("TABLES: Unable to parse '%s'!  Error code = %i.\n", filename, rval));
		return;
	} 

	read_file_text(filename, CF_TYPE_TABLES);
	reset_parse();

	// for each overlay...
	while (optional_string("$")) {

		stuff_string(name, F_NAME, HELP_MAX_NAME_LENGTH);

		overlay_id = help_overlay_get_index(name);

		if (overlay_id < 0) {
			if (num_help_overlays >= MAX_HELP_OVERLAYS) {
				Warning(LOCATION, "Could not load help overlay after '%s' as maximum number of help overlays was reached (Max is %d)", help_overlaylist[overlay_id - 1].name, MAX_HELP_OVERLAYS);

				if (!skip_to_string("$end")) {
					Error(LOCATION, "Couldn't find $end. Help.tbl or -hlp.tbm is invalid.\n");
				}

				continue;
			} else {
				overlay_id = num_help_overlays;
				strcpy_s(help_overlaylist[overlay_id].name, name);
				num_help_overlays++;
			}
		}

		// clear out counters in the overlay struct
		help_overlaylist[overlay_id].plinecount = 0;
		help_overlaylist[overlay_id].textcount = 0;
		help_overlaylist[overlay_id].rbracketcount = 0;
		help_overlaylist[overlay_id].lbracketcount = 0;

		help_overlaylist[overlay_id].fontlist.clear();
		help_overlaylist[overlay_id].plinelist.clear();
		help_overlaylist[overlay_id].textlist.clear();
		help_overlaylist[overlay_id].rbracketlist.clear();
		help_overlaylist[overlay_id].lbracketlist.clear();

		if (optional_string("+resolutions")) {
			stuff_int(&help_overlaylist[overlay_id].num_resolutions);
		} else {
			help_overlaylist[overlay_id].num_resolutions = 2;
		}

		if (help_overlaylist[overlay_id].num_resolutions < 1) {
			Error(LOCATION, "+resolutions in %s is %d. (Must be 1 or greater)", filename, help_overlaylist[overlay_id].num_resolutions);
		}

		if (optional_string("+font")) {
			int font;
			for (i=0; i<help_overlaylist[overlay_id].num_resolutions; i++) {
				stuff_int(&font);
				help_overlaylist[overlay_id].fontlist.push_back(font);
			}
		} else {
			for (i=0; i<help_overlaylist[overlay_id].num_resolutions; i++) {
				help_overlaylist[overlay_id].fontlist.push_back(FONT1);
			}
		}

		for (i=0; i<help_overlaylist[overlay_id].num_resolutions; i++) {
			help_overlaylist[overlay_id].plinelist.push_back(pline_temp);
			help_overlaylist[overlay_id].textlist.push_back(text_temp);
			help_overlaylist[overlay_id].rbracketlist.push_back(rbracket_temp);
			help_overlaylist[overlay_id].lbracketlist.push_back(lbracket_temp);
		}
		
		int type;
		// read in all elements for this overlay
		while ((type = required_string_one_of(5, "+pline", "+text", "+right_bracket", "+left_bracket", "$end")) != 4) {	// Doing it this way means an error lists "$end" at the end, which seems appropriate. -MageKing17

			switch (type) {
			case 0:	// +pline
				required_string("+pline");
				currcount = help_overlaylist[overlay_id].plinecount;
				int a, b;		// temp vars to read in int before cast to float;

				// read number of pline vertices
				stuff_int(&vtxcount);
				// get vertex coordinates for each resolution
				for (i = 0; i < help_overlaylist[overlay_id].num_resolutions; i++) {
					help_overlaylist[overlay_id].plinelist.at(i).push_back(pline_temp2);
					for (j = 0; j < vtxcount; j++) {
						help_overlaylist[overlay_id].plinelist.at(i).at(currcount).vtx.push_back(vec3d_temp);
						help_overlaylist[overlay_id].plinelist.at(i).at(currcount).vtxcount = vtxcount;
						stuff_int(&a);
						stuff_int(&b);
						help_overlaylist[overlay_id].plinelist.at(i).at(currcount).vtx.at(j).xyz.x = (float)a;
						help_overlaylist[overlay_id].plinelist.at(i).at(currcount).vtx.at(j).xyz.y = (float)b;
						help_overlaylist[overlay_id].plinelist.at(i).at(currcount).vtx.at(j).xyz.z = 0.0f;
					}
				}

				help_overlaylist[overlay_id].plinecount++;
				break;
			case 1:	// +text
				required_string("+text");
				currcount = help_overlaylist[overlay_id].textcount;

				// get coordinates for each resolution
				for (i = 0; i < help_overlaylist[overlay_id].num_resolutions; i++) {
					help_overlaylist[overlay_id].textlist.at(i).push_back(text_temp2);
					stuff_int(&(help_overlaylist[overlay_id].textlist.at(i).at(currcount).x_coord));
					stuff_int(&(help_overlaylist[overlay_id].textlist.at(i).at(currcount).y_coord));
				}

				// get string (always use the first resolution)
				stuff_string(buf, F_MESSAGE, sizeof(buf));
				help_overlaylist[overlay_id].textlist.at(0).at(currcount).string = vm_strdup(buf);

				help_overlaylist[overlay_id].textcount++;
				break;
			case 2: // +right_bracket
				required_string("+right_bracket");
				currcount = help_overlaylist[overlay_id].rbracketcount;

				// get coordinates for each resolution
				for (i = 0; i < help_overlaylist[overlay_id].num_resolutions; i++) {
					help_overlaylist[overlay_id].rbracketlist.at(i).push_back(rbracket_temp2);
					stuff_int(&(help_overlaylist[overlay_id].rbracketlist.at(i).at(currcount).x_coord));
					stuff_int(&(help_overlaylist[overlay_id].rbracketlist.at(i).at(currcount).y_coord));
				}

				help_overlaylist[overlay_id].rbracketcount++;
				break;
			case 3: // +left_bracket
				required_string("+left_bracket");
				currcount = help_overlaylist[overlay_id].lbracketcount;

				// get coordinates for each resolution
				for (i = 0; i < help_overlaylist[overlay_id].num_resolutions; i++) {
					help_overlaylist[overlay_id].lbracketlist.at(i).push_back(lbracket_temp2);
					stuff_int(&(help_overlaylist[overlay_id].lbracketlist.at(i).at(currcount).x_coord));
					stuff_int(&(help_overlaylist[overlay_id].lbracketlist.at(i).at(currcount).y_coord));
				}

				help_overlaylist[overlay_id].lbracketcount++;
				break;
			case -1:
				// -noparseerrors is set
				break;
			case 4: // $end
			default:
				Assertion(false, "This should never happen.\n");
				break;
			}
		}		// end while
		required_string("$end");
	}		// end while
}
예제 #28
0
void parse_gamesnd_old(game_snd* gs)
{
	int is_3d;
	int temp;

	stuff_string(gs->filename, F_NAME, MAX_FILENAME_LEN, ",");

	if (!stricmp(gs->filename, NOX("empty")))
	{
		gs->filename[0] = 0;
		advance_to_eoln(NULL);
		return;
	}
	Mp++;

	stuff_int(&temp);

	if (temp > 0)
	{
		gs->preload = true;
	}

	stuff_float(&gs->default_volume);

	stuff_int(&is_3d);

	if (is_3d)
	{
		gs->flags |= GAME_SND_USE_DS3D;
		stuff_int(&gs->min);
		stuff_int(&gs->max);
	}
	else
	{
		gs->min = 0;
		gs->max = 0;

		// silly retail, not abiding by its own format...
		if (!stricmp(gs->filename, "l_hit.wav") || !stricmp(gs->filename, "m_hit.wav"))
		{
			int temp_min, temp_max;

			ignore_gray_space();
			if (stuff_int_optional(&temp_min, true) == 2)
			{
				ignore_gray_space();
				if (stuff_int_optional(&temp_max, true) == 2)
				{
					mprintf(("Dutifully converting retail sound %s, '%s' to a 3D sound...\n", gs->name.c_str(), gs->filename));
					is_3d = 1;

					gs->flags |= GAME_SND_USE_DS3D;
					gs->min = temp_min;
					gs->max = temp_max;
				}
			}
		}
	}

	// check for extra values per Mantis #2408
	ignore_gray_space();
	if (stuff_int_optional(&temp, true) == 2)
	{
		Warning(LOCATION, "Unexpected extra value %d found for sound '%s' (filename '%s')!  Check the format of the sounds.tbl (or .tbm) entry.", temp, gs->name.c_str(), gs->filename);
	}

	advance_to_eoln(NULL);
}
예제 #29
0
// parses help.tbl and populates help_overlaylist[]
void parse_helptbl()
{
	int overlay_id, currcount;
	char buf[HELP_MAX_STRING_LENGTH + 1];
	int i, rval;

	// open localization
	lcl_ext_open();

	if ((rval = setjmp(parse_abort)) != 0)
	{
		mprintf(("TABLES: Unable to parse '%s'!  Error code = %i.\n", HELP_OVERLAY_FILENAME, rval));
		lcl_ext_close();
		return;
	}

	read_file_text(HELP_OVERLAY_FILENAME, CF_TYPE_TABLES);

	// for each overlay...
	for (overlay_id = 0; overlay_id < MAX_HELP_OVERLAYS; overlay_id++)
	{

		reset_parse();
		skip_to_string(help_overlay_section_names[overlay_id]);

		// clear out counters in the overlay struct
		help_overlaylist[overlay_id].plinecount = 0;
		help_overlaylist[overlay_id].textcount = 0;
		help_overlaylist[overlay_id].rbracketcount = 0;
		help_overlaylist[overlay_id].lbracketcount = 0;

		// read in all elements for this overlay
		while (!(check_for_string("$end")))
		{

			if (optional_string("+pline"))
			{

				currcount = help_overlaylist[overlay_id].plinecount;
				int a, b;		// temp vars to read in int before cast to float;

				if (currcount < HELP_MAX_ITEM)
				{
					// read number of pline vertices
					stuff_int(&help_overlaylist[overlay_id].plinelist[GR_640][currcount].vtxcount);		// note that it is read into GR_640
					// help_overlaylist[overlay_id].plinelist[GR_1024][currcount].vtxcount = help_overlaylist[overlay_id].plinelist[GR_640][currcount].vtxcount;			// set equal to 1024 version vertex count to prevent bugs
					Assert(help_overlaylist[overlay_id].plinelist[GR_640][currcount].vtxcount <=
						HELP_MAX_PLINE_VERTICES);
					// get 640x480 vertex coordinates
					for (i = 0; i < help_overlaylist[overlay_id].plinelist[GR_640][currcount].vtxcount; i++)
					{
						stuff_int(&a);
						stuff_int(&b);
						help_overlaylist[overlay_id].plinelist[GR_640][currcount].vtx[i].xyz.x = (float)a;
						help_overlaylist[overlay_id].plinelist[GR_640][currcount].vtx[i].xyz.y = (float)b;
						help_overlaylist[overlay_id].plinelist[GR_640][currcount].vtx[i].xyz.z = 0.0f;
						help_overlaylist[overlay_id].plinelist[GR_640][currcount].pvtx[i] = &help_overlaylist[
							overlay_id].plinelist[GR_640][currcount].vtx[i];
					}
					// get 1024x768 vertex coordinates
					for (i = 0; i < help_overlaylist[overlay_id].plinelist[GR_640][currcount].vtxcount; i++)
					{
						stuff_int(&a);
						stuff_int(&b);
						help_overlaylist[overlay_id].plinelist[GR_1024][currcount].vtx[i].xyz.x = (float)a;
						help_overlaylist[overlay_id].plinelist[GR_1024][currcount].vtx[i].xyz.y = (float)b;
						help_overlaylist[overlay_id].plinelist[GR_1024][currcount].vtx[i].xyz.z = 0.0f;
						help_overlaylist[overlay_id].plinelist[GR_1024][currcount].pvtx[i] = &help_overlaylist[
							overlay_id].plinelist[GR_1024][currcount].vtx[i];
					}
				}

				//mprintf(("Found pline - start location (%f,%f), end location (%f,%f)\n", help_overlaylist[overlay_id].plinelist[GR_640][currcount].vtx[0].xyz.x, help_overlaylist[overlay_id].plinelist[GR_640][currcount].vtx[0].xyz.y, help_overlaylist[overlay_id].plinelist[GR_640][currcount].vtx[2].xyz.x, help_overlaylist[overlay_id].plinelist[GR_640][currcount].vtx[2].xyz.y));
				help_overlaylist[overlay_id].plinecount++;

			}
			else if (optional_string("+text"))
			{

				currcount = help_overlaylist[overlay_id].textcount;

				if (currcount < HELP_MAX_ITEM)
				{
					// get 640x480 coordinates
					stuff_int(&(help_overlaylist[overlay_id].textlist[GR_640][currcount].x_coord));
					stuff_int(&(help_overlaylist[overlay_id].textlist[GR_640][currcount].y_coord));
					// get 1024x768 coordinates
					stuff_int(&(help_overlaylist[overlay_id].textlist[GR_1024][currcount].x_coord));
					stuff_int(&(help_overlaylist[overlay_id].textlist[GR_1024][currcount].y_coord));

					// get string (always use the GR_640 one)
					stuff_string(buf, F_MESSAGE, sizeof(buf));
					help_overlaylist[overlay_id].textlist[GR_640][currcount].string = vm_strdup(buf);

					//mprintf(("Found text %d on overlay %d - location (%d,%d) @ 640x480 :: location (%d,%d) @ 1024x768\n", currcount, overlay_id, help_overlaylist[overlay_id].textlist[GR_640][currcount].x_coord, help_overlaylist[overlay_id].textlist[GR_640][currcount].y_coord, help_overlaylist[overlay_id].textlist[GR_1024][currcount].x_coord, help_overlaylist[overlay_id].textlist[GR_1024][currcount].x_coord));
					help_overlaylist[overlay_id].textcount++;
				}

			}
			else if (optional_string("+right_bracket"))
			{

				currcount = help_overlaylist[overlay_id].rbracketcount;

				if (currcount < HELP_MAX_ITEM)
				{
					// get 640x480 coordinates
					stuff_int(&(help_overlaylist[overlay_id].rbracketlist[GR_640][currcount].x_coord));
					stuff_int(&(help_overlaylist[overlay_id].rbracketlist[GR_640][currcount].y_coord));
					// get 1024x768 coordinates
					stuff_int(&(help_overlaylist[overlay_id].rbracketlist[GR_1024][currcount].x_coord));
					stuff_int(&(help_overlaylist[overlay_id].rbracketlist[GR_1024][currcount].y_coord));

					//mprintf(("Found rbracket %d on overlay %d - location (%d,%d) @ 640x480 :: location (%d,%d) @ 1024x768\n", currcount, overlay_id, help_overlaylist[overlay_id].rbracketlist[GR_640][currcount].x_coord, help_overlaylist[overlay_id].rbracketlist[GR_640][currcount].y_coord, help_overlaylist[overlay_id].rbracketlist[GR_1024][currcount].x_coord, help_overlaylist[overlay_id].rbracketlist[GR_1024][currcount].y_coord));
					help_overlaylist[overlay_id].rbracketcount++;
				}

			}
			else if (optional_string("+left_bracket"))
			{

				currcount = help_overlaylist[overlay_id].lbracketcount;

				if (currcount < HELP_MAX_ITEM)
				{
					// get 640x480 coordinates
					stuff_int(&(help_overlaylist[overlay_id].lbracketlist[GR_640][currcount].x_coord));
					stuff_int(&(help_overlaylist[overlay_id].lbracketlist[GR_640][currcount].y_coord));
					// get 1024x768 coordinates
					stuff_int(&(help_overlaylist[overlay_id].lbracketlist[GR_1024][currcount].x_coord));
					stuff_int(&(help_overlaylist[overlay_id].lbracketlist[GR_1024][currcount].y_coord));

					//mprintf(("Found lbracket %d on overlay %d - location (%d,%d) @ 640x480 :: location (%d,%d) @ 1024x768\n", currcount, overlay_id, help_overlaylist[overlay_id].lbracketlist[GR_640][currcount].x_coord, help_overlaylist[overlay_id].lbracketlist[GR_640][currcount].y_coord, help_overlaylist[overlay_id].lbracketlist[GR_1024][currcount].x_coord, help_overlaylist[overlay_id].lbracketlist[GR_1024][currcount].y_coord));
					help_overlaylist[overlay_id].lbracketcount++;
				}

			}
			else
			{
				// help.tbl is corrupt
				Assert(0);

			}		// end if

		}		// end while
	}		// end for

	// close localization
	lcl_ext_close();
}
예제 #30
0
// game init
void ssm_init()
{	
	int rval;
	ssm_info bogus, *s;
	char weapon_name[NAME_LENGTH];

	if ((rval = setjmp(parse_abort)) != 0) {
		mprintf(("TABLES: Unable to parse '%s'!  Error code = %i.\n", "ssm.tbl", rval));
		return;
	}

	read_file_text("ssm.tbl", CF_TYPE_TABLES);
	reset_parse();

	// parse the table
	Ssm_info_count = 0;
	while(!optional_string("#end")){
		// another ssm definition
		if(optional_string("$SSM:")){
			// pointer to info struct
			if(Ssm_info_count >= MAX_SSM_TYPES){
				s = &bogus;
			} else {
				s = &Ssm_info[Ssm_info_count];
			}

			// name
			stuff_string(s->name, F_NAME, NAME_LENGTH);

			// stuff data
			required_string("+Weapon:");
			stuff_string(weapon_name, F_NAME, NAME_LENGTH);
			required_string("+Count:");
			stuff_int(&s->count);
			required_string("+WarpRadius:");
			stuff_float(&s->warp_radius);
			required_string("+WarpTime:");
			stuff_float(&s->warp_time);
			// According to fireballs.cpp, "Warp lifetime must be at least 4 seconds!"
			if ( (s->warp_time) < 4.0f) {
				// So let's warn them before they try to use it, shall we?
				Warning(LOCATION, "Expected a '+WarpTime:' value equal or greater than 4.0, found '%f' in weapon '%s'.\n Setting to 4.0, please check and set to a number 4.0 or greater!\n", s->warp_time, weapon_name);
				// And then make the Assert obsolete -- Zacam
				s->warp_time = 4.0f;
			}
			required_string("+Radius:");
			stuff_float(&s->radius);
			required_string("+Offset:");
			stuff_float(&s->offset);
			if (optional_string("+HUD Message:")) 
				stuff_boolean(&s->send_message);
			else
				s->send_message = true;
			if (optional_string("+Custom Message:")) {
				stuff_string(s->message, F_NAME, NAME_LENGTH);
				s->use_custom_message = true;
			}

			// see if we have a valid weapon
			s->weapon_info_index = -1;
			s->weapon_info_index = weapon_info_lookup(weapon_name);
			if(s->weapon_info_index >= 0){
				// valid
				Ssm_info_count++;
			}
		}
	}
}