Example #1
0
void enumerate_capture_devices(OpenALInformation* info) {
	info->capture_devices.clear();
	info->default_capture_device.clear();

	auto default_device = alcGetString( NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER );
	if (default_device != nullptr) {
		info->default_capture_device = default_device;
	}

	if ( alcIsExtensionPresent(NULL, (const ALCchar*)"ALC_ENUMERATION_EXT") == AL_TRUE ) {
		const char *all_devices = (const char*) alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER);

		const char *str_list = all_devices;
		size_t ext_length = 0;

		if ( (str_list != NULL) && ((ext_length = strlen(str_list)) > 0) ) {
			while (ext_length) {
				info->capture_devices.push_back( SCP_string(str_list));

				str_list += (ext_length + 1);
				ext_length = strlen(str_list);
			}
		}
	} else {
		if (default_device) {
			info->capture_devices.push_back(SCP_string(default_device));
		}
	}
}
void hud_sourced_print(int source, const char *msg)
{
    if ( !strlen(msg) ) {
        nprintf(("Warning", "HUD ==> attempt to print a 0 length string in msg window\n"));
        return;
    }

    // add message to the scrollback log first
    hud_add_msg_to_scrollback(msg, source, Missiontime);

    HUD_message_data new_msg;

    new_msg.text = SCP_string(msg);
    new_msg.source = source;
    new_msg.x = 0;

    HUD_msg_buffer.push_back(new_msg);

    // Invoke the scripting hook
    Script_system.SetHookVar("Text", 's', const_cast<char*>(msg));
    Script_system.SetHookVar("SourceType", 'i', &source);

    Script_system.RunCondition(CHA_HUDMSGRECEIVED);

    Script_system.RemHookVars(2, "Text", "SourceType");

}
	VFNTFont::VFNTFont(font *fnt) : FSFont()
	{
		Assertion(fnt != NULL, "Invalid font passed to constructor of VFNTFont!");

		this->fontPtr = fnt;

		setName(SCP_string(fnt->filename));
	}
static void cache_program_binary(GLuint program, const SCP_string& hash) {
	if (!do_shader_caching()) {
		return;
	}
	
	GR_DEBUG_SCOPE("Saving shader binary");

	GLint size;
	glGetProgramiv(program, GL_PROGRAM_BINARY_LENGTH, &size);

	if (size <= 0) {
		// No binary available (I'm looking at you Mesa...)
		return;
	}

	SCP_vector<uint8_t> binary;
	binary.resize((size_t) size);
	GLenum binary_fmt;
	GLsizei length;
	glGetProgramBinary(program, (GLsizei) binary.size(), &length, &binary_fmt, binary.data());
	if (length == 0) {
		return;
	}

	auto base_filename = SCP_string("ogl_shader-") + hash;

	auto metadata_name = base_filename + ".json";
	auto binary_name = base_filename + ".bin";

	auto metadata_fp = cfopen(metadata_name.c_str(), "wb", CFILE_NORMAL, CF_TYPE_CACHE, false,
	                          CF_LOCATION_ROOT_USER | CF_LOCATION_ROOT_GAME | CF_LOCATION_TYPE_ROOT);
	if (!metadata_fp) {
		mprintf(("Could not open shader cache metadata file!\n"));
		return;
	}

	auto metadata = json_pack("{sI}", "format", (json_int_t)binary_fmt);
	if (json_dump_callback(metadata, json_write_callback, metadata_fp, 0) != 0) {
		mprintf(("Failed to write shader cache metadata file!\n"));
		cfclose(metadata_fp);
		return;
	}
	cfclose(metadata_fp);
	json_decref(metadata);

	auto binary_fp = cfopen(binary_name.c_str(), "wb", CFILE_NORMAL, CF_TYPE_CACHE, false,
	                        CF_LOCATION_ROOT_USER | CF_LOCATION_ROOT_GAME | CF_LOCATION_TYPE_ROOT);
	if (!binary_fp) {
		mprintf(("Could not open shader cache binary file!\n"));
		return;
	}
	cfwrite(binary.data(), 1, (int) binary.size(), binary_fp);
	cfclose(binary_fp);
}
void campaign_editor::OnChangeMainHall() 
{
	CString str;
	UpdateData(TRUE);

	if (Cur_campaign_mission >= 0)
	{
		GetDlgItem(IDC_MAIN_HALL)->GetWindowText(str);
		Campaign.missions[Cur_campaign_mission].main_hall = SCP_string((LPCTSTR)(str));
	}
}
Example #6
0
void hud_sourced_print(int source, char *msg)
{
	if ( !strlen(msg) ) {
		nprintf(("Warning", "HUD ==> attempt to print a 0 length string in msg window\n"));
		return;
	}

	// add message to the scrollback log first
	hud_add_msg_to_scrollback(msg, source, Missiontime);

	HUD_message_data new_msg;

	new_msg.text = SCP_string(msg);
	new_msg.source = source;
	new_msg.x = 0;

	HUD_msg_buffer.push_back(new_msg);
}
static bool load_cached_shader_binary(opengl::ShaderProgram* program, const SCP_string& hash) {
	if (!do_shader_caching()) {
		return false;
	}

	auto base_filename = SCP_string("ogl_shader-") + hash;

	auto metadata = base_filename + ".json";
	auto binary = base_filename + ".bin";

	auto metadata_fp = cfopen(metadata.c_str(), "rb", CFILE_NORMAL, CF_TYPE_CACHE, false,
	                          CF_LOCATION_ROOT_USER | CF_LOCATION_ROOT_GAME | CF_LOCATION_TYPE_ROOT);
	if (!metadata_fp) {
		nprintf(("ShaderCache", "Metadata file does not exist.\n"));
		return false;
	}

	auto size = cfilelength(metadata_fp);
	SCP_string metadata_content;
	metadata_content.resize((size_t) size);
	cfread(&metadata_content[0], 1, size, metadata_fp);

	cfclose(metadata_fp);

	auto metadata_root = json_loads(metadata_content.c_str(), 0, nullptr);
	if (!metadata_root) {
		mprintf(("Loading of cache metadata failed! Falling back to GLSL shader...\n"));
		return false;
	}

	json_int_t format;
	if (json_unpack(metadata_root, "{sI}", "format", &format) != 0) {
		mprintf(("Failed to unpack values from metadata JSON! Falling back to GLSL shader...\n"));
		return false;
	}
	auto binary_format = (GLenum) format;
	json_decref(metadata_root);

	bool supported = false;
	for (auto supported_fmt : GL_binary_formats) {
		if ((GLenum)supported_fmt == binary_format) {
			supported = true;
			break;
		}
	}

	if (!supported) {
		// This can happen in case an implementation stops supporting a particular binary format
		nprintf(("ShaderCache", "Unsupported binary format %d encountered in shader cache.\n", binary_format));
		return false;
	}

	auto binary_fp = cfopen(binary.c_str(), "rb", CFILE_NORMAL, CF_TYPE_CACHE, false,
	                        CF_LOCATION_ROOT_USER | CF_LOCATION_ROOT_GAME | CF_LOCATION_TYPE_ROOT);
	if (!binary_fp) {
		nprintf(("ShaderCache", "Binary file does not exist.\n"));
		return false;
	}
	
	GR_DEBUG_SCOPE("Loading cached shader");
	
	SCP_vector<uint8_t> buffer;
	int length = cfilelength(binary_fp);
	buffer.resize((size_t) length);
	cfread(&buffer[0], 1, length, binary_fp);

	cfclose(binary_fp);

	// Load the data!
	glProgramBinary(program->getShaderHandle(), binary_format, buffer.data(), (GLsizei) buffer.size());

	// Check the status...
	GLint status;
	glGetProgramiv(program->getShaderHandle(), GL_LINK_STATUS, &status);

	return status == GL_TRUE;
}
Example #8
0
void credits_init()
{
	int i;
	credits_screen_buttons *b;

	// pre-initialize
	Credits_num_images = DEFAULT_NUM_IMAGES;
	Credits_artwork_index = -1;

	// this is moved up here so we can override it if desired
	strcpy_s(Credits_music_name, "Cinema");

	// parse credits early so as to set up any overrides (for music and such)
	Credits_parsed = false;
	credits_parse();

	// we could conceivably have specified a number of images but not an index,
	// so if that's the case, set the value here
	if (Credits_artwork_index < 0) {
		Credits_artwork_index = rand() % Credits_num_images;
	}

	int credits_spooled_music_index = event_music_get_spooled_music_index(Credits_music_name);	
	if(credits_spooled_music_index != -1){
		char *credits_wavfile_name = Spooled_music[credits_spooled_music_index].filename;		
		if(credits_wavfile_name != NULL){
			credits_load_music(credits_wavfile_name);
		}
	}

	// Use this id to trigger the start of music playing on the briefing screen
	Credits_music_begin_timestamp = timestamp(Credits_music_delay);

	Credits_frametime = 0;
	Credits_last_time = timer_get_milliseconds();
	
	if (!Credits_parsed)
	{
		Credit_text_parts.push_back(SCP_string("No credits available.\n"));
	}
	else
	{
		switch (SCP_credits_position)
		{
			case START:
				Credit_text_parts.insert(Credit_text_parts.begin(), fs2_open_credit_text);
				break;

			case END:
				Credit_text_parts.push_back(fs2_open_credit_text);
				break;

			default:
				Error(LOCATION, "Unimplemented credits position %d. Get a coder!", (int) SCP_credits_position);
				break;
		}
	}

	int ch;
	SCP_vector<SCP_string>::iterator iter;

	for (iter = Credit_text_parts.begin(); iter != Credit_text_parts.end(); ++iter)
	{
		for (SCP_string::iterator ii = iter->begin(); ii != iter->end(); ++ii)
		{
			ch = *ii;
			switch (ch)
			{
				case -4:
					ch = 129;
					break;

				case -28:
					ch = 132;
					break;

				case -10:
					ch = 148;
					break;

				case -23:
					ch = 130;
					break;

				case -30:
					ch = 131;
					break;

				case -25:
					ch = 135;
					break;

				case -21:
					ch = 137;
					break;

				case -24:
					ch = 138;
					break;

				case -17:
					ch = 139;
					break;

				case -18:
					ch = 140;
					break;

				case -60:
					ch = 142;
					break;

				case -55:
					ch = 144;
					break;

				case -12:
					ch = 147;
					break;

				case -14:
					ch = 149;
					break;

				case -5:
					ch = 150;
					break;

				case -7:
					ch = 151;
					break;

				case -42:
					ch = 153;
					break;

				case -36:
					ch = 154;
					break;

				case -31:
					ch = 160;
					break;

				case -19:
					ch = 161;
					break;

				case -13:
					ch = 162;
					break;

				case -6:
					ch = 163;
					break;

				case -32:
					ch = 133;
					break;

				case -22:
					ch = 136;
					break;

				case -20:
					ch = 141;
					break;
			}

			*ii = (char) ch;
		}
	}

	int temp_h;
	int h = 0;

	for (iter = Credit_text_parts.begin(); iter != Credit_text_parts.end(); ++iter)
	{
		gr_get_string_size(NULL, &temp_h, iter->c_str(), (int)iter->length());

		h = h + temp_h;
	}

	Credit_start_pos = i2fl(Credits_text_coords[gr_screen.res][CREDITS_H_COORD]);
	Credit_stop_pos = -i2fl(h);
	Credit_position = Credit_start_pos;

	Ui_window.create(0, 0, gr_screen.max_w_unscaled, gr_screen.max_h_unscaled, 0);
	Ui_window.set_mask_bmap(Credits_bitmap_mask_fname[gr_screen.res]);
	common_set_interface_palette("InterfacePalette");  // set the interface palette

	for (i=0; i<NUM_BUTTONS; i++) {
		b = &Buttons[i][gr_screen.res];

		b->button.create(&Ui_window, "", b->x, b->y, 60, 30, (i < 2), 1);
		// set up callback for when a mouse first goes over a button
		b->button.set_highlight_action(common_play_highlight_sound);
		b->button.set_bmaps(b->filename);
		b->button.link_hotspot(b->hotspot);
	}

	// add some text
	Ui_window.add_XSTR("Technical Database", 1055, Buttons[TECH_DATABASE_BUTTON][gr_screen.res].xt,  Buttons[TECH_DATABASE_BUTTON][gr_screen.res].yt, &Buttons[TECH_DATABASE_BUTTON][gr_screen.res].button, UI_XSTR_COLOR_GREEN);
	Ui_window.add_XSTR("Mission Simulator", 1056, Buttons[SIMULATOR_BUTTON][gr_screen.res].xt,  Buttons[SIMULATOR_BUTTON][gr_screen.res].yt, &Buttons[SIMULATOR_BUTTON][gr_screen.res].button, UI_XSTR_COLOR_GREEN);
	Ui_window.add_XSTR("Cutscenes", 1057, Buttons[CUTSCENES_BUTTON][gr_screen.res].xt,  Buttons[CUTSCENES_BUTTON][gr_screen.res].yt, &Buttons[CUTSCENES_BUTTON][gr_screen.res].button, UI_XSTR_COLOR_GREEN);
	Ui_window.add_XSTR("Credits", 1058, Buttons[CREDITS_BUTTON][gr_screen.res].xt,  Buttons[CREDITS_BUTTON][gr_screen.res].yt, &Buttons[CREDITS_BUTTON][gr_screen.res].button, UI_XSTR_COLOR_GREEN);
	Ui_window.add_XSTR("Exit", 1420, Buttons[EXIT_BUTTON][gr_screen.res].xt,  Buttons[EXIT_BUTTON][gr_screen.res].yt, &Buttons[EXIT_BUTTON][gr_screen.res].button, UI_XSTR_COLOR_PINK);

	if (Player->flags & PLAYER_FLAGS_IS_MULTI) {
		Buttons[SIMULATOR_BUTTON][gr_screen.res].button.disable();
		Buttons[CUTSCENES_BUTTON][gr_screen.res].button.disable();
	}

	Buttons[EXIT_BUTTON][gr_screen.res].button.set_hotkey(KEY_CTRLED | KEY_ENTER);

	Background_bitmap = bm_load(Credits_bitmap_fname[gr_screen.res]);

	Credits_bmps.resize(Credits_num_images);
	for (i=0; i<Credits_num_images; i++) {
		Credits_bmps[i] = -1;
	}
}
Example #9
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;
	}
}
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;
	}
}
Example #11
0
/**
 * Used to start profiling a section of code. A section started by profile_begin needs to be closed off by calling
 * profile_end with the same argument.
 * @param name A globally unique string that will be displayed in the HUD readout
 */
void profile_begin(const char* name)
{
    if (Cmdline_json_profiling)
    {
        std::lock_guard<std::mutex> guard(json_mutex);

        tracing_data data;

        data.name = name;

        data.pid = get_pid();
        data.tid = get_tid();

        data.enter = true;
        data.time = timer_get_nanoseconds();

        if (do_gpu_queries) {
            data.gpu_query = get_query_object();
            gr_query_value(data.gpu_query, QueryType::Timestamp);
        } else {
            data.gpu_query = -1;
        }

        current_frame_data.push_back(data);
    }

    if (Cmdline_frame_profile)
    {
        int parent = -1;
        for (int i = 0; i < (int)samples.size(); i++) {
            if ( !samples[i].open_profiles ) {
                continue;
            }

            samples[i].num_children++;

            if (samples[i].num_children == 1) {
                // this is our direct parent for this new sample
                parent = i;
            }
        }

        for(int i = 0; i < (int)samples.size(); i++) {
            if( !strcmp(samples[i].name.c_str(), name) && samples[i].parent == parent ) {
                // found the profile sample
                samples[i].open_profiles++;
                samples[i].profile_instances++;
                samples[i].start_time = timer_get_microseconds();
                Assert(samples[i].open_profiles == 1); // max 1 open at once
                return;
            }
        }

        // create a new profile sample
        profile_sample new_sample;

        new_sample.name = SCP_string(name);
        new_sample.open_profiles = 1;
        new_sample.profile_instances = 1;
        new_sample.accumulator = 0;
        new_sample.start_time = timer_get_microseconds();
        new_sample.children_sample_time = 0;
        new_sample.num_children = 0;
        new_sample.parent = parent;

        samples.push_back(new_sample);
    }
}
static bool load_cached_shader_binary(opengl::ShaderProgram* program, SCP_string hash) {
	if (!do_shader_caching()) {
		return false;
	}

	auto base_filename = SCP_string("ogl_shader-") + hash;

	auto metadata = base_filename + ".json";
	auto binary = base_filename + ".bin";

	auto metadata_fp = cfopen(metadata.c_str(), "rb", CFILE_NORMAL, CF_TYPE_CACHE);
	if (!metadata_fp) {
		nprintf(("ShaderCache", "Metadata file does not exist.\n"));
		return false;
	}

	auto size = cfilelength(metadata_fp);
	SCP_string metadata_content;
	metadata_content.resize((size_t) size);
	cfread(&metadata_content[0], 1, size, metadata_fp);

	cfclose(metadata_fp);

	auto metadata_root = json_loads(metadata_content.c_str(), 0, nullptr);
	if (!metadata_root) {
		mprintf(("Loading of cache metadata failed! Falling back to GLSL shader...\n"));
		return false;
	}

	json_int_t format;
	if (json_unpack(metadata_root, "{sI}", "format", &format) != 0) {
		mprintf(("Failed to unpack values from metadata JSON! Falling back to GLSL shader...\n"));
		return false;
	}
	auto binary_format = (GLenum) format;
	json_decref(metadata_root);

	auto binary_fp = cfopen(binary.c_str(), "rb", CFILE_NORMAL, CF_TYPE_CACHE);
	if (!binary_fp) {
		nprintf(("ShaderCache", "Binary file does not exist.\n"));
		return false;
	}
	
	GR_DEBUG_SCOPE("Loading cached shader");
	
	SCP_vector<uint8_t> buffer;
	int length = cfilelength(binary_fp);
	buffer.resize((size_t) length);
	cfread(&buffer[0], 1, length, binary_fp);

	cfclose(binary_fp);

	// Load the data!
	glProgramBinary(program->getShaderHandle(), binary_format, buffer.data(), (GLsizei) buffer.size());

	// Check the status...
	GLint status;
	glGetProgramiv(program->getShaderHandle(), GL_LINK_STATUS, &status);

	return status == GL_TRUE;
}
void multi_options_read_config()
{
	CFILE *in;
	char str[512];
	char *tok = NULL;

	// set default value for the global multi options
	Multi_options_g.reset();

	ushort forced_port = (ushort)os_config_read_uint(NULL, "ForcePort", 0);
	Multi_options_g.port = (Cmdline_network_port >= 0) ? (ushort)Cmdline_network_port : forced_port == 0 ? (ushort)DEFAULT_GAME_PORT : forced_port;
	Multi_options_g.log = (Cmdline_multi_log) ? 1 : 0;


	// read in the config file
	in = cfopen(MULTI_CFG_FILE, "rt", CFILE_NORMAL, CF_TYPE_DATA);
	
	// if we failed to open the config file, user default settings
	if (in == NULL) {
		nprintf(("Network","Failed to open network config file, using default settings\n"));		
	} else {
		while ( !cfeof(in) ) {
			// read in the game info
			memset(str, 0, 512);
			cfgets(str, 512, in);

			// parse the first line
			tok = strtok(str, " \t");

			// check the token
			if (tok != NULL) {
				drop_leading_white_space(tok);
				drop_trailing_white_space(tok);			
			} else {
				continue;
			}		

			// all possible options

			// only standalone cares about the following options
			if (Is_standalone) {
				// setup PXO mode
				if ( SETTING("+pxo") ) {
					NEXT_TOKEN();
					if (tok != NULL) {
						strncpy(Multi_fs_tracker_channel, tok, MAX_PATH-1);
					}
				} else
				// set the standalone server's permanent name
				if	( SETTING("+name") ) {
					NEXT_TOKEN();
					if (tok != NULL) {
						strncpy(Multi_options_g.std_pname, tok, STD_NAME_LEN);
					}
				} else
				// standalone won't allow voice transmission
				if ( SETTING("+no_voice") ) {
					Multi_options_g.std_voice = 0;
				} else
				// set the max # of players on the standalone
				if ( SETTING("+max_players") ) {
					NEXT_TOKEN();
					if (tok != NULL) {
						if ( !((atoi(tok) < 1) || (atoi(tok) > MAX_PLAYERS)) ) {
							Multi_options_g.std_max_players = atoi(tok);
						}
					}
				} else
				// ban a player
				if ( SETTING("+ban") ) {
					NEXT_TOKEN();
					if (tok != NULL) {
						std_add_ban(tok);
					}
				} else
				// set the standalone host password
				if ( SETTING("+passwd") ) {
					NEXT_TOKEN();
					if (tok != NULL) {
						strncpy(Multi_options_g.std_passwd, tok, STD_PASSWD_LEN);
#ifdef _WIN32
						// yuck
						extern HWND Multi_std_host_passwd;
						SetWindowText(Multi_std_host_passwd, Multi_options_g.std_passwd);
#else
						// TODO: get password ?
						// argh, gonna have to figure out how to do this - mharris 07/07/2002
#endif
					}
				} else
				// set standalone to low updates
				if ( SETTING("+low_update") ) {
					Multi_options_g.std_datarate = OBJ_UPDATE_LOW;
				} else
				// set standalone to medium updates
				if ( SETTING("+med_update") ) {
					Multi_options_g.std_datarate = OBJ_UPDATE_MEDIUM;
				} else
				// set standalone to high updates
				if ( SETTING("+high_update") ) {
					Multi_options_g.std_datarate = OBJ_UPDATE_HIGH;
				} else
				// set standalone to high updates
				if ( SETTING("+lan_update") ) {
					Multi_options_g.std_datarate = OBJ_UPDATE_LAN;
				} else
				// use pxo flag
				if ( SETTING("+use_pxo") ) {
					Om_tracker_flag = 1;
				} else
				// standalone pxo login user
				if ( SETTING("+pxo_login") ) {
					NEXT_TOKEN();
					if (tok != NULL) {
						strncpy(Multi_options_g.std_pxo_login, tok, MULTI_TRACKER_STRING_LEN);
					}
				} else
				// standalone pxo login password
				if ( SETTING("+pxo_password") ) {
					NEXT_TOKEN();
					if (tok != NULL) {
						strncpy(Multi_options_g.std_pxo_password, tok, MULTI_TRACKER_STRING_LEN);
					}
				} else
				if ( SETTING("+webui_root") ) {
					NEXT_TOKEN();
					if (tok != NULL) {
						Multi_options_g.webuiRootDirectory = SCP_string(tok);
					}
				} else
				if ( SETTING("+webapi_username") ) {
					NEXT_TOKEN();
					if (tok != NULL) {
						Multi_options_g.webapiUsername = SCP_string(tok);
					}
				} else
				if ( SETTING("+webapi_password") ) {
					NEXT_TOKEN();
					if (tok != NULL) {
						Multi_options_g.webapiPassword = SCP_string(tok);
					}
				} else
				if ( SETTING("+webapi_server_port") ) {
					NEXT_TOKEN();
					if (tok != NULL) {
						long int result = strtol(tok, NULL, 10);
						if(result <= 0 || result > USHRT_MAX) {
							mprintf(("ERROR: Invalid or out of range webapi_server_port '%s' specified in multi.cfg, must be integer between 1024 and %i.\n", tok, USHRT_MAX));
						}
						else if(result < 1024) {
							mprintf(("ERROR: webapi_server_port '%ld' in multi.cfg is too low, must be between 1024 and %d.\n", result, USHRT_MAX));
						}
						else {
							mprintf(("Using webapi_server_port '%ld' from multi.cfg.\n", result));
							Multi_options_g.webapiPort = (ushort) result;
						}
					}
				}
			}

			// ... common to all modes ...

			// ip addr of user tracker
			if ( SETTING("+user_server") ) {
				NEXT_TOKEN();
				if (tok != NULL) {
					strcpy_s(Multi_options_g.user_tracker_ip, tok);
				}
			} else
			// ip addr of game tracker
			if ( SETTING("+game_server") ) {
				NEXT_TOKEN();
				if (tok != NULL) {
					strcpy_s(Multi_options_g.game_tracker_ip, tok);
				}
			} else
			// port to use for the game/user tracker (FS2NetD)
			if ( SETTING("+server_port") ) {
				NEXT_TOKEN();
				if (tok != NULL) {
					strcpy_s(Multi_options_g.tracker_port, tok);
				}
			} else
			// ip addr of pxo chat server
			if ( SETTING("+chat_server") ) {
				NEXT_TOKEN();
				if (tok != NULL) {
					strcpy_s(Multi_options_g.pxo_ip, tok);
				}
			} else
			// url of pilot rankings page
			if ( SETTING("+rank_url") ) {
				NEXT_TOKEN();
				if (tok != NULL) {
					strcpy_s(Multi_options_g.pxo_rank_url, tok);
				}
			} else
			// url of pxo account create page
			if ( SETTING("+create_url") ) {
				NEXT_TOKEN();
				if (tok != NULL) {
					strcpy_s(Multi_options_g.pxo_create_url, tok);
				}
			} else
			// url of pxo account verify page
			if ( SETTING("+verify_url") ) {
				NEXT_TOKEN();
				if (tok != NULL) {
					strcpy_s(Multi_options_g.pxo_verify_url, tok);
				}
			} else
			// url of pxo banners
			if ( SETTING("+banner_url") ) {
				NEXT_TOKEN();
				if (tok != NULL) {
					strcpy_s(Multi_options_g.pxo_banner_url, tok);
				}
			} else
			// set the max datarate for high updates
			if ( SETTING("+datarate") ) {
				NEXT_TOKEN();
				if (tok != NULL) {
					if ( atoi(tok) >= 4000 ) {
						Multi_options_g.datarate_cap = atoi(tok);
					}
				}			
			} else
			// get the proxy server
			if ( SETTING("+http_proxy") ) {
				NEXT_TOKEN();
				if (tok != NULL) {
					char *ip = strtok(tok, ":");

					if (ip != NULL) {
						strcpy_s(Multi_options_proxy, ip);
					}

					ip = strtok(NULL, "");

					if (ip != NULL) {
						Multi_options_proxy_port = (ushort)atoi(ip);
					} else {
						strcpy_s(Multi_options_proxy, "");
					}
				}
			}
		}

		// close the config file
		cfclose(in);
		in = NULL;
	}

#ifndef _WIN32
	if (Is_standalone) {
		std_configLoaded(&Multi_options_g);
	}
#endif
}