Example #1
0
void pilotfile::plr_read_multiplayer()
{
    // netgame options
    p->m_server_options.squad_set = cfread_ubyte(cfp);
    p->m_server_options.endgame_set = cfread_ubyte(cfp);
    p->m_server_options.flags = cfread_int(cfp);
    p->m_server_options.respawn = cfread_uint(cfp);
    p->m_server_options.max_observers = cfread_ubyte(cfp);
    p->m_server_options.skill_level = cfread_ubyte(cfp);
    p->m_server_options.voice_qos = cfread_ubyte(cfp);
    p->m_server_options.voice_token_wait = cfread_int(cfp);
    p->m_server_options.voice_record_time = cfread_int(cfp);
    p->m_server_options.mission_time_limit = (fix)cfread_int(cfp);
    p->m_server_options.kill_limit = cfread_int(cfp);

    // local options
    p->m_local_options.flags = cfread_int(cfp);
    p->m_local_options.obj_update_level = cfread_int(cfp);

    // netgame protocol
    Multi_options_g.protocol = cfread_int(cfp);

    if (Multi_options_g.protocol == NET_VMT) {
        Multi_options_g.protocol = NET_TCP;
    }

    Assert( (Multi_options_g.protocol == NET_IPX) || (Multi_options_g.protocol == NET_TCP) );
}
void pilotfile_convert::csg_import_techroom()
{
	int idx, list_size = 0;
	bool visible;
	unsigned char in = 0;

	// intel entry count
	int intel_count = cfread_int(cfp);

	csg->ships_techroom.reserve( csg->ship_list.size() );
	csg->weapons_techroom.reserve( csg->weapon_list.size() );
	csg->intel_techroom.reserve( intel_count );

	// ships
	list_size = (int)csg->ship_list.size();

	for (idx = 0; idx < list_size; idx++) {
		in = cfread_ubyte(cfp);

		if (in > 1) {
			throw std::runtime_error("Data check failure (techroom-ship)!");
		}

		visible = (in == 1) ? true : false;

		csg->ships_techroom.push_back( visible );
	}

	// weapons
	list_size = (int)csg->weapon_list.size();

	for (idx = 0; idx < list_size; idx++) {
		in = cfread_ubyte(cfp);

		if (in > 1) {
			throw std::runtime_error("Data check failure (techroom-weapon)!");
		}

		visible = (in == 1) ? true : false;

		csg->weapons_techroom.push_back( visible );
	}

	// intel
	list_size = intel_count;

	for (idx = 0; idx < list_size; idx++) {
		in = cfread_ubyte(cfp);

		if (in > 1) {
			throw std::runtime_error("Data check failure (techroom-intel)!");
		}

		visible = (in == 1) ? true : false;

		csg->intel_techroom.push_back( visible );
	}
}
Example #3
0
void pilotfile::csg_read_techroom()
{
	int idx, list_size = 0;
	ubyte visible;

	if ( !m_have_info ) {
		throw "Techroom before Info!";
	}

	// visible ships
	list_size = (int)ship_list.size();
	for (idx = 0; idx < list_size; idx++) {
		visible = cfread_ubyte(cfp);

		if (visible) {
			if (ship_list[idx].index >= 0) {
				Ship_info[ship_list[idx].index].flags.set(Ship::Info_Flags::In_tech_database);
			} else {
				m_data_invalid = true;
			}
		}
	}

	// visible weapons
	list_size = (int)weapon_list.size();
	for (idx = 0; idx < list_size; idx++) {
		visible = cfread_ubyte(cfp);

		if (visible) {
			if (weapon_list[idx].index >= 0) {
				Weapon_info[weapon_list[idx].index].wi_flags |= WIF_IN_TECH_DATABASE;
			} else {
				m_data_invalid = true;
			}
		}
	}

	// visible intel entries
	list_size = (int)intel_list.size();
	for (idx = 0; idx < list_size; idx++) {
		visible = cfread_ubyte(cfp);

		if (visible) {
			if (intel_list[idx].index >= 0) {
				Intel_info[intel_list[idx].index].flags |= IIF_IN_TECH_DATABASE;
			} else {
				m_data_invalid = true;
			}
		}
	}

	// if anything we need/use was missing then it should be considered fatal
	if (m_data_invalid) {
		throw "Invalid data for CSG!";
	}
}
void pilotfile_convert::plr_import_controls()
{
	int idx;
	config_item con;

	unsigned char num_controls = cfread_ubyte(cfp);

	if ( !num_controls ) {
		return;
	}

	// it may be less than 118, but it shouldn't be more than 118
	if (num_controls > 118) {
		throw "Data check failure in controls!";
	}

	plr->controls.reserve(num_controls);

	for (idx = 0; idx < num_controls; idx++) {
		con.key_id = cfread_short(cfp);

		if (con.key_id == 255) {
			con.key_id = -1;
		}

		con.joy_id = cfread_short(cfp);

		if (con.joy_id == 255) {
			con.joy_id = -1;
		}

		plr->controls.push_back( con );
	}
}
void pilotfile_convert::plr_import_hud()
{
	int idx;
	conv_color c;

	plr->hud_show_flags = cfread_int(cfp);
	plr->hud_show_flags2 = cfread_int(cfp);

	plr->hud_popup_flags = cfread_int(cfp);
	plr->hud_popup_flags2 = cfread_int(cfp);

	plr->hud_num_lines = cfread_ubyte(cfp);
	plr->hud_rp_flags = cfread_int(cfp);
	plr->hud_rp_dist = cfread_int(cfp);

	for (idx = 0; idx < 39; idx++) {
		cfread(&c, sizeof(conv_color), 1, cfp);

		if ( (c.alphacolor != -1) || (c.is_alphacolor != 1) ) {
			throw "Data check failure in hud!";
		}

		plr->hud_colors[idx][0] = c.red;
		plr->hud_colors[idx][1] = c.green;
		plr->hud_colors[idx][2] = c.blue;
		plr->hud_colors[idx][3] = c.alpha;
	}
}
void pilotfile::plr_read_flags()
{
	// tips?
	p->tips = (int)cfread_ubyte(cfp);

	// saved flags
	p->save_flags = cfread_int(cfp);

	// listing mode (single or campaign missions
	p->readyroom_listing_mode = cfread_int(cfp);

	// briefing auto-play
	p->auto_advance = cfread_int(cfp);

	// special rank setting (to avoid having to read all stats on verify)
	// will be the multi rank
	// if there's a valid CSG, this will be overwritten
	p->stats.rank = cfread_int(cfp);

	if (version > 0) 
	{
		p->player_was_multi = cfread_int(cfp);
	} else 
	{
		p->player_was_multi = 0; // Default to single player
	}

	// which language was this pilot created with
	if (version > 1) {
		cfread_string_len(p->language, sizeof(p->language), cfp);
	} else {
		// if we don't know, default to the current language setting
		lcl_get_language_name(p->language);
	}
}
Example #7
0
void pilotfile::plr_read_flags()
{
    // tips?
    p->tips = (int)cfread_ubyte(cfp);

    // saved flags
    p->save_flags = cfread_int(cfp);

    // listing mode (single or campaign missions
    p->readyroom_listing_mode = cfread_int(cfp);

    // briefing auto-play
    p->auto_advance = cfread_int(cfp);

    // special rank setting (to avoid having to read all stats on verify)
    p->stats.rank = cfread_int(cfp);

    if (version > 0)
    {
        p->player_was_multi = cfread_int(cfp);
    } else
    {
        p->player_was_multi = 0; // Default to single player
    }
}
void pilotfile_convert::plr_import_multiplayer()
{
	plr->multi_squad_set = cfread_ubyte(cfp);
	plr->multi_endgame_set = cfread_ubyte(cfp);
	plr->multi_flags = cfread_int(cfp);
	plr->multi_respawn = cfread_uint(cfp);
	plr->multi_max_observers = cfread_ubyte(cfp);
	plr->multi_skill_level = cfread_ubyte(cfp);
	plr->multi_voice_qos = cfread_ubyte(cfp);
	plr->multi_voice_token_wait = cfread_int(cfp);
	plr->multi_voice_record_time = cfread_int(cfp);
	plr->multi_time_limit = cfread_int(cfp);
	plr->multi_kill_limit = cfread_int(cfp);

	plr->multi_local_flags = cfread_int(cfp);
	plr->multi_local_update_level = cfread_int(cfp);
}
Example #9
0
void pilotfile::plr_read_hud()
{
    int idx;

    // flags
    HUD_config.show_flags = cfread_int(cfp);
    HUD_config.show_flags2 = cfread_int(cfp);

    HUD_config.popup_flags = cfread_int(cfp);
    HUD_config.popup_flags2 = cfread_int(cfp);

    // settings
    HUD_config.num_msg_window_lines = cfread_ubyte(cfp);

    HUD_config.rp_flags = cfread_int(cfp);
    HUD_config.rp_dist = cfread_int(cfp);

    // basic colors
    HUD_config.main_color = cfread_int(cfp);
    HUD_color_alpha = cfread_int(cfp);

    if (HUD_color_alpha < HUD_COLOR_ALPHA_USER_MIN) {
        HUD_color_alpha = HUD_COLOR_ALPHA_DEFAULT;
    }

    hud_config_set_color(HUD_config.main_color);

    // gauge-specific colors
    int num_gauges = cfread_int(cfp);

    for (idx = 0; idx < num_gauges; idx++) {
        ubyte red = cfread_ubyte(cfp);
        ubyte green = cfread_ubyte(cfp);
        ubyte blue = cfread_ubyte(cfp);
        ubyte alpha = cfread_ubyte(cfp);

        if (idx >= NUM_HUD_GAUGES) {
            continue;
        }

        HUD_config.clr[idx].red = red;
        HUD_config.clr[idx].green = green;
        HUD_config.clr[idx].blue = blue;
        HUD_config.clr[idx].alpha = alpha;
    }
}
Example #10
0
void pilotfile::csg_read_flags()
{
	// tips?
	p->tips = (int)cfread_ubyte(cfp);

	// avoid having to read everything to get the rank
	if (csg_ver >= 5) {
		p->stats.rank = cfread_int(cfp);
	}
}
// -----------------------------------------------------------------------------
//	anim_read_header()
//
// Read the header of a .ani file.  Below is the format of a .ani header
//
//	#bytes		|	description
//	2			|	obsolete, kept for compatibility with old versions
//	2			|	version number
//	2			|	fps
//	1			|	transparent red value
//  1			|	transparent green value
//	1			|	transparent blue value
//	2			|	width
//	2			|	height
//	2			|	number of frames
//	1			|	packer code
//	763			|	palette
//	2			|	number of key frames
//	2			|	key frame number	}		repeats
//	4			|	key frame offset	}		repeats
//	4			|	compressed data length
//
void anim_read_header(anim *ptr, CFILE *fp)
{
	ptr->width = cfread_short(fp);
	// If first 2 bytes are zero, this means we are using a new format, which includes
	// a version, and fps values. This is only done since a version number was not included
	// in the original header.

	// default
	Color_xparent.red = 0;
	Color_xparent.green = 255;
	Color_xparent.blue = 0;

	if ( ptr->width == 0 ) {
		ptr->version = cfread_short(fp);
		ptr->fps = cfread_short(fp);

		// version 2 added a custom transparency color
		if ( ptr->version >= 2 ) {
			cfread(&Color_xparent.red, 1, 1, fp);
			cfread(&Color_xparent.green, 1, 1, fp);
			cfread(&Color_xparent.blue, 1, 1, fp);
		}

		ptr->width = cfread_short(fp);
	}
	else {
		ptr->version = 0;
		ptr->fps = 30;
	}
	
	ptr->height = cfread_short(fp);

#ifndef NDEBUG
	// get size of ani compared to power of 2
	int r, floor_pow;
	r = ptr->height;
	floor_pow = 0;
	
	while(r >= 2) {
		r /= 2;
		floor_pow++;
	}

	int floor_size = (int) pow(2.0, floor_pow);
	int diff = ptr->height - floor_size;
	float waste = 100.0f * float((floor_size - diff))/(2.0f *(float)floor_size);

	if (diff != 0) {
		if (ptr->height > 16) {
			mprintf(("ANI %s with size %dx%d (%.1f%% wasted)\n", ptr->name, ptr->width, ptr->height, waste));
		}
	}
#endif

	ptr->total_frames = cfread_short(fp);
	ptr->packer_code = cfread_ubyte(fp);
	cfread(&ptr->palette, 256, 3, fp);
	ptr->num_keys = cfread_short(fp);

	// store xparent colors
	ptr->xparent_r = Color_xparent.red;
	ptr->xparent_g = Color_xparent.green;
	ptr->xparent_b = Color_xparent.blue;

	if(ptr->total_frames == ptr->num_keys){
		ptr->flags |= ANF_ALL_KEYFRAMES;
	}
}
Example #12
0
void pilotfile::csg_read_info()
{
	char t_string[NAME_LENGTH+1] = { '\0' };
	index_list_t ilist;
	int idx, list_size = 0;
	ubyte allowed = 0;

	if ( !m_have_flags ) {
		throw "Info before Flags!";
	}

	//
	// NOTE: lists may contain missing/invalid entries for current data
	//       this is not necessarily fatal
	//

	// ship list (NOTE: may contain more than MAX_SHIP_CLASSES)
	list_size = cfread_int(cfp);

	for (idx = 0; idx < list_size; idx++) {
		cfread_string_len(t_string, NAME_LENGTH, cfp);

		ilist.name = t_string;
		ilist.index = ship_info_lookup(t_string);

		ship_list.push_back(ilist);
	}

	// weapon list (NOTE: may contain more than MAX_WEAPON_TYPES)
	list_size = cfread_int(cfp);

	for (idx = 0; idx < list_size; idx++) {
		cfread_string_len(t_string, NAME_LENGTH, cfp);

		ilist.name = t_string;
		ilist.index = weapon_info_lookup(t_string);

		weapon_list.push_back(ilist);
	}

	// intel list (NOTE: may contain more than MAX_INTEL_ENTRIES)
	list_size = cfread_int(cfp);

	for (idx = 0; idx < list_size; idx++) {
		cfread_string_len(t_string, NAME_LENGTH, cfp);

		ilist.name = t_string;
		ilist.index = intel_info_lookup(t_string);

		intel_list.push_back(ilist);
	}

	// medals list (NOTE: may contain more than Num_medals)
	list_size = cfread_int(cfp);

	for (idx = 0; idx < list_size; idx++) {
		cfread_string_len(t_string, NAME_LENGTH, cfp);

		ilist.name = t_string;
		ilist.index = medals_info_lookup(t_string);

		medals_list.push_back(ilist);
	}

	// last ship flown (index into ship_list)
	idx = cfread_int(cfp);

	// check the idx is within bounds
	Assertion ((idx < (int)ship_list.size()), "Campaign file contains an incorrect value for the last flown ship class. No data in ship_list for ship number %d.", idx); 
	if (idx >= (int)ship_list.size())
		idx = -1;
	else if (idx != -1)
		p->last_ship_flown_si_index = ship_list[idx].index;
	else
		p->last_ship_flown_si_index = -1;

	// progression state
	Campaign.prev_mission = cfread_int(cfp);
	Campaign.next_mission = cfread_int(cfp);

	// loop state
	Campaign.loop_reentry = cfread_int(cfp);
	Campaign.loop_enabled = cfread_int(cfp);

	// missions completed
	Campaign.num_missions_completed = cfread_int(cfp);

	// allowed ships
	list_size = (int)ship_list.size();
	for (idx = 0; idx < list_size; idx++) {
		allowed = cfread_ubyte(cfp);

		if (allowed) {
			if (ship_list[idx].index >= 0) {
				Campaign.ships_allowed[ship_list[idx].index] = 1;
			} else {
				m_data_invalid = true;
			}
		}
	}

	// allowed weapons
	list_size = (int)weapon_list.size();
	for (idx = 0; idx < list_size; idx++) {
		allowed = cfread_ubyte(cfp);

		if (allowed) {
			if (weapon_list[idx].index >= 0) {
				Campaign.weapons_allowed[weapon_list[idx].index] = 1;
			} else {
				m_data_invalid = true;
			}
		}
	}

	if (csg_ver >= 2) {
		// single/campaign squad name & image
		cfread_string_len(p->s_squad_name, NAME_LENGTH, cfp);
		cfread_string_len(p->s_squad_filename, MAX_FILENAME_LEN, cfp);
	}

	// if anything we need/use was missing then it should be considered fatal
	if (m_data_invalid) {
		throw "Invalid data for CSG!";
	}
}
void pilotfile_convert::csg_import(bool inferno)
{
	Assert( cfp != NULL );

	char name[35];

	unsigned int csg_id = cfread_uint(cfp);

	if (csg_id != 0xbeefcafe) {
		throw std::runtime_error("Invalid file signature!");
	}

	fver = cfread_uint(cfp);

	if (fver != 15) {
		throw std::runtime_error("Unsupported file version!");
	}

	// campaign type (single/multi)
	csg->sig = cfread_int(cfp);

	// trash
	cfread_string_len(name, sizeof(name), cfp);

	csg->prev_mission = cfread_int(cfp);
	csg->next_mission = cfread_int(cfp);
	csg->loop_reentry = cfread_int(cfp);
	csg->loop_enabled = cfread_int(cfp);

	csg_import_ships_weapons();

	csg_import_missions(inferno);

	csg->main_hall = cfread_ubyte(cfp);

	csg_import_red_alert();

	csg_import_techroom();

	csg_import_loadout();

	csg_import_stats();

	csg->cutscenes = cfread_int(cfp);

	// final data checks
	if ( csg->ship_list.size() != csg->ships_allowed.size() ) {
		throw std::runtime_error("Data check failure (ship size)!");
	} else if ( csg->ship_list.size() != csg->ships_techroom.size() ) {
		throw std::runtime_error("Data check failure (ship size)!");
	} else if ( csg->weapon_list.size() != csg->weapons_allowed.size() ) {
		throw std::runtime_error("Data check failure (weapon size)!");
	} else if ( csg->weapon_list.size() != csg->weapons_techroom.size() ) {
		throw std::runtime_error("Data check failure (weapon size)!");
	} else if ( csg->intel_list.size() != csg->intel_techroom.size() ) {
		throw std::runtime_error("Data check failure (intel size)!");
	}


	// and... we're done!
}
Example #14
0
/*
 * get_csg_rank: this function is called from plr.cpp & is
 * tightly linked with pilotfile::verify()
 */
bool pilotfile::get_csg_rank(int *rank)
{
	player t_csg;

	// set player ptr first thing
	p = &t_csg;

	// filename has already been set
	cfp = cfopen((char*)filename.c_str(), "rb", CFILE_NORMAL, CF_TYPE_PLAYERS);

	if ( !cfp ) {
		mprintf(("CSG => Unable to open '%s'!\n", filename.c_str()));
		return false;
	}

	unsigned int csg_id = cfread_uint(cfp);

	if (csg_id != CSG_FILE_ID) {
		mprintf(("CSG => Invalid header id for '%s'!\n", filename.c_str()));
		csg_close();
		return false;
	}

	// version, now used
	csg_ver = cfread_ubyte(cfp);

	mprintf(("CSG => Get Rank from '%s' with version %d...\n", filename.c_str(), (int)csg_ver));

	// the point of all this: read in the CSG contents
	while ( !m_have_flags && !cfeof(cfp) ) {
		ushort section_id = cfread_ushort(cfp);
		uint section_size = cfread_uint(cfp);

		size_t start_pos = cftell(cfp);
		size_t offset_pos;

		// safety, to help protect against long reads
		cf_set_max_read_len(cfp, section_size);

		try {
			switch (section_id) {
				case Section::Flags:
					mprintf(("CSG => Parsing:  Flags...\n"));
					m_have_flags = true;
					csg_read_flags();
					break;

				default:
					break;
			}
		} catch (cfile::max_read_length &msg) {
			// read to max section size, move to next section, discarding
			// extra/unknown data
			mprintf(("CSG => (0x%04x) %s\n", section_id, msg.what()));
		} catch (const char *err) {
			mprintf(("CSG => ERROR: %s\n", err));
			csg_close();
			return false;
		}

		// reset safety catch
		cf_set_max_read_len(cfp, 0);

		// skip to next section (if not already there)
		offset_pos = (start_pos + section_size) - cftell(cfp);

		if (offset_pos) {
			mprintf(("CSG => Warning: (0x%04x) Short read, information may have been lost!\n", section_id));
			cfseek(cfp, (int)offset_pos, CF_SEEK_CUR);
		}
	}

	// this is what we came for...
	*rank = p->stats.rank;

	mprintf(("CSG => Get Rank complete!\n"));

	// cleanup & return
	csg_close();

	return true;
}
Example #15
0
bool pilotfile::load_savefile(const char *campaign)
{
	char base[_MAX_FNAME] = { '\0' };
	std::ostringstream buf;

	if (Game_mode & GM_MULTIPLAYER) {
		return false;
	}

	if ( (campaign == NULL) || !strlen(campaign) ) {
		return false;
	}

	// set player ptr first thing
	Assert( (Player_num >= 0) && (Player_num < MAX_PLAYERS) );
	p = &Players[Player_num];

	// build up filename for the savefile...
	_splitpath((char*)campaign, NULL, NULL, base, NULL);

	buf << p->callsign << "." << base << ".csg";

	filename = buf.str().c_str();

	// if campaign file doesn't exist, abort so we don't load irrelevant data
	buf.str(std::string());
	buf << base << FS_CAMPAIGN_FILE_EXT;
	if ( !cf_exists_full((char*)buf.str().c_str(), CF_TYPE_MISSIONS) ) {
		mprintf(("CSG => Unable to find campaign file '%s'!\n", buf.str().c_str()));
		return false;
	}

	// we need to reset this early, in case open fails and we need to create
	m_data_invalid = false;

	// open it, hopefully...
	cfp = cfopen((char*)filename.c_str(), "rb", CFILE_NORMAL, CF_TYPE_PLAYERS);

	if ( !cfp ) {
		mprintf(("CSG => Unable to open '%s' for reading!\n", filename.c_str()));
		return false;
	}

	unsigned int csg_id = cfread_uint(cfp);

	if (csg_id != CSG_FILE_ID) {
		mprintf(("CSG => Invalid header id for '%s'!\n", filename.c_str()));
		csg_close();
		return false;
	}

	// version, now used
	csg_ver = cfread_ubyte(cfp);

	mprintf(("CSG => Loading '%s' with version %d...\n", filename.c_str(), (int)csg_ver));

	csg_reset_data();

	// the point of all this: read in the CSG contents
	while ( !cfeof(cfp) ) {
		ushort section_id = cfread_ushort(cfp);
		uint section_size = cfread_uint(cfp);

		size_t start_pos = cftell(cfp);

		// safety, to help protect against long reads
		cf_set_max_read_len(cfp, section_size);

		try {
			switch (section_id) {
				case Section::Flags:
					mprintf(("CSG => Parsing:  Flags...\n"));
					m_have_flags = true;
					csg_read_flags();
					break;

				case Section::Info:
					mprintf(("CSG => Parsing:  Info...\n"));
					m_have_info = true;
					csg_read_info();
					break;

				case Section::Variables:
					mprintf(("CSG => Parsing:  Variables...\n"));
					csg_read_variables();
					break;

				case Section::HUD:
					mprintf(("CSG => Parsing:  HUD...\n"));
					csg_read_hud();
					break;

				case Section::RedAlert:
					mprintf(("CSG => Parsing:  RedAlert...\n"));
					csg_read_redalert();
					break;

				case Section::Scoring:
					mprintf(("CSG => Parsing:  Scoring...\n"));
					csg_read_stats();
					break;

				case Section::Loadout:
					mprintf(("CSG => Parsing:  Loadout...\n"));
					csg_read_loadout();
					break;

				case Section::Techroom:
					mprintf(("CSG => Parsing:  Techroom...\n"));
					csg_read_techroom();
					break;

				case Section::Missions:
					mprintf(("CSG => Parsing:  Missions...\n"));
					csg_read_missions();
					break;

				case Section::Settings:
					mprintf(("CSG => Parsing:  Settings...\n"));
					csg_read_settings();
					break;

				case Section::Controls:
					mprintf(("CSG => Parsing:  Controls...\n"));
					csg_read_controls();
					break;

				case Section::Cutscenes:
					mprintf(("CSG => Parsing:  Cutscenes...\n"));
					csg_read_cutscenes();
					break;

				case Section::LastMissions:
					mprintf(("CSG => Parsing:  Last Missions...\n"));
					csg_read_lastmissions();
					break;

				default:
					mprintf(("CSG => Skipping unknown section 0x%04x!\n", section_id));
					break;
			}
		} catch (cfile::max_read_length &msg) {
			// read to max section size, move to next section, discarding
			// extra/unknown data
			mprintf(("CSG => Warning: (0x%04x) %s\n", section_id, msg.what()));
		} catch (const char *err) {
			mprintf(("CSG => ERROR: %s\n", err));
			csg_close();
			return false;
		}

		// reset safety catch
		cf_set_max_read_len(cfp, 0);

		// skip to next section (if not already there)
		size_t offset_pos = (start_pos + section_size) - cftell(cfp);

		if (offset_pos) {
			mprintf(("CSG => Warning: (0x%04x) Short read, information may have been lost!\n", section_id));
			cfseek(cfp, (int)offset_pos, CF_SEEK_CUR);
		}
	}

	// if the campaign (for whatever reason) doesn't have a squad image, use the multi one
	if (p->s_squad_filename[0] == '\0') {
		strcpy_s(p->s_squad_filename, p->m_squad_filename);
	}
	player_set_squad_bitmap(p, p->s_squad_filename, false);

	mprintf(("CSG => Loading complete!\n"));

	// cleanup and return
	csg_close();

	return true;
}
std::uint8_t pilot::BinaryFileHandler::readUByte(const char*) {
	return cfread_ubyte(_cfp);
}
Example #17
0
bool pilotfile::load_player(const char *callsign, player *_p)
{
    // if we're a standalone server in multiplayer, just fill in some bogus values
    // since we don't have a pilot file
    if ( (Game_mode & GM_MULTIPLAYER) && (Game_mode & GM_STANDALONE_SERVER) ) {
        Player->insignia_texture = -1;
        strcpy_s(Player->callsign, NOX("Standalone"));
        strcpy_s(Player->short_callsign, NOX("Standalone"));

        return true;
    }

    // set player ptr first thing
    p = _p;

    if ( !p ) {
        Assert( (Player_num >= 0) && (Player_num < MAX_PLAYERS) );
        p = &Players[Player_num];
    }

    filename = callsign;
    filename += ".plr";

    if ( filename.size() == 4 ) {
        mprintf(("PLR => Invalid filename '%s'!\n", filename.c_str()));
        return false;
    }

    cfp = cfopen((char*)filename.c_str(), "rb", CFILE_NORMAL, CF_TYPE_PLAYERS);

    if ( !cfp ) {
        mprintf(("PLR => Unable to open '%s' for reading!\n", filename.c_str()));
        return false;
    }

    unsigned int plr_id = cfread_uint(cfp);

    if (plr_id != PLR_FILE_ID) {
        mprintf(("PLR => Invalid header id for '%s'!\n", filename.c_str()));
        plr_close();
        return false;
    }

    // version, should be able to just ignore it
    version = cfread_ubyte(cfp);

    mprintf(("PLR => Loading '%s' with version %d...\n", filename.c_str(), version));

    plr_reset_data();

    // the point of all this: read in the PLR contents
    while ( !cfeof(cfp) ) {
        ushort section_id = cfread_ushort(cfp);
        uint section_size = cfread_uint(cfp);

        size_t start_pos = cftell(cfp);

        // safety, to help protect against long reads
        cf_set_max_read_len(cfp, section_size);

        try {
            switch (section_id) {
            case Section::Flags:
                mprintf(("PLR => Parsing:  Flags...\n"));
                m_have_flags = true;
                plr_read_flags();
                break;

            case Section::Info:
                mprintf(("PLR => Parsing:  Info...\n"));
                m_have_info = true;
                plr_read_info();
                break;

            case Section::Variables:
                mprintf(("PLR => Parsing:  Variables...\n"));
                plr_read_variables();
                break;

            case Section::HUD:
                mprintf(("PLR => Parsing:  HUD...\n"));
                plr_read_hud();
                break;

            case Section::Scoring:
                mprintf(("PLR => Parsing:  Scoring...\n"));
                plr_read_stats();
                break;

            case Section::ScoringMulti:
                mprintf(("PLR => Parsing:  ScoringMulti...\n"));
                plr_read_stats_multi();
                break;

            case Section::Multiplayer:
                mprintf(("PLR => Parsing:  Multiplayer...\n"));
                plr_read_multiplayer();
                break;

            case Section::Controls:
                mprintf(("PLR => Parsing:  Controls...\n"));
                plr_read_controls();
                break;

            case Section::Settings:
                mprintf(("PLR => Parsing:  Settings...\n"));
                plr_read_settings();
                break;

            default:
                mprintf(("PLR => Skipping unknown section 0x%04x!\n", section_id));
                break;
            }
        } catch (cfile::max_read_length &msg) {
            // read to max section size, move to next section, discarding
            // extra/unknown data
            mprintf(("PLR => (0x%04x) %s\n", section_id, msg.what()));
        } catch (const char *err) {
            mprintf(("PLR => ERROR: %s\n", err));
            plr_close();
            return false;
        }

        // reset safety catch
        cf_set_max_read_len(cfp, 0);

        // skip to next section (if not already there)
        size_t offset_pos = (start_pos + section_size) - cftell(cfp);

        if (offset_pos) {
            cfseek(cfp, offset_pos, CF_SEEK_CUR);
        }
    }

    // restore the callsign into the Player structure
    strcpy_s(p->callsign, callsign);

    // restore the truncated callsign into Player structure
    pilot_set_short_callsign(p, SHORT_CALLSIGN_PIXEL_W);

    player_set_squad_bitmap(p, p->m_squad_filename, true);

    hud_squadmsg_save_keys();

    // set last pilot
    os_config_write_string(NULL, "LastPlayer", (char*)callsign);

    mprintf(("PLR => Loading complete!\n"));

    // cleanup and return
    plr_close();

    return true;
}
bool pilotfile::verify(const char *fname, int *rank, char *valid_language)
{
	player t_plr;

	// set player ptr first thing
	p = &t_plr;

	filename = fname;

	if ( filename.size() == 4 ) {
		mprintf(("PLR => Invalid filename '%s'!\n", filename.c_str()));
		return false;
	}

	cfp = cfopen((char*)filename.c_str(), "rb", CFILE_NORMAL, CF_TYPE_PLAYERS);

	if ( !cfp ) {
		mprintf(("PLR => Unable to open '%s'!\n", filename.c_str()));
		return false;
	}

	unsigned int plr_id = cfread_uint(cfp);

	if (plr_id != PLR_FILE_ID) {
		mprintf(("PLR => Invalid header id for '%s'!\n", filename.c_str()));
		plr_close();
		return false;
	}

	// version, now used
	version = cfread_ubyte(cfp);

	mprintf(("PLR => Verifying '%s' with version %d...\n", filename.c_str(), (int)version));

	// the point of all this: read in the PLR contents
	while ( !(m_have_flags && m_have_info) && !cfeof(cfp) ) {
		ushort section_id = cfread_ushort(cfp);
		uint section_size = cfread_uint(cfp);

		size_t start_pos = cftell(cfp);

		// safety, to help protect against long reads
		cf_set_max_read_len(cfp, section_size);

		try {
			switch (section_id) {
				case Section::Flags:
					mprintf(("PLR => Parsing:  Flags...\n"));
					m_have_flags = true;
					plr_read_flags();
					break;

				// now reading the Info section to get the campaign
				// and be able to lookup the campaign rank
				case Section::Info:
					mprintf(("PLR => Parsing:  Info...\n"));
					m_have_info = true;
					plr_read_info();
					break;

				default:
					break;
			}
		} catch (cfile::max_read_length &msg) {
			// read to max section size, move to next section, discarding
			// extra/unknown data
			mprintf(("PLR => (0x%04x) %s\n", section_id, msg.what()));
		} catch (const char *err) {
			mprintf(("PLR => ERROR: %s\n", err));
			plr_close();
			return false;
		}

		// reset safety catch
		cf_set_max_read_len(cfp, 0);

		// skip to next section (if not already there)
		size_t offset_pos = (start_pos + section_size) - cftell(cfp);

		if (offset_pos) {
			mprintf(("PLR => Warning: (0x%04x) Short read, information may have been lost!\n", section_id));
			cfseek(cfp, offset_pos, CF_SEEK_CUR);
		}
	}

	if (valid_language) {
		strncpy(valid_language, p->language, sizeof(p->language));
	}

	// need to cleanup early to ensure everything is OK for use in the CSG next
	// also means we can't use *p from now on, use t_plr instead for a few vars
	plr_close();

	if (rank) {
		// maybe get the rank from the CSG
		if ( !(Game_mode & GM_MULTIPLAYER) ) {
			// build the csg filename
			// since filename/fname was validated above, perform less safety checks here
			filename = fname;
			filename = filename.replace(filename.find_last_of('.')+1,filename.npos, t_plr.current_campaign);
			filename.append(".csg");

			if (!this->get_csg_rank(rank)) {
				// if we failed to get the csg rank, default to multi rank
				*rank = t_plr.stats.rank;
			}
		} else {
			// if the CSG isn't valid, or for multi, use this rank
			*rank = t_plr.stats.rank;
		}
	}

	mprintf(("PLR => Verifying complete!\n"));

	return true;
}
void pilotfile_convert::plr_import()
{
	char name[35];
	int idx;

	unsigned int plr_id = cfread_uint(cfp);

	if (plr_id != 0x46505346) {
		throw "Invalid file signature!";
	}

	fver = cfread_uint(cfp);

	if ( (fver != 142) && (fver != 242) ) {
		throw "Unsupported file version!";
	}

	// multi flag
	plr->is_multi = (int)cfread_ubyte(cfp);

	// rank
	plr->rank = cfread_int(cfp);

	// mainhall, don't need it
	if (fver < 242) {
		cfread_ubyte(cfp);
	}

	plr->tips = cfread_int(cfp);

	if ( (plr->tips < 0) || (plr->tips > 1) ) {
		throw "Data check failure!";
	}

	cfread_string_len(plr->image_filename, sizeof(plr->image_filename), cfp);
	cfread_string_len(plr->squad_name, sizeof(plr->squad_name), cfp);
	cfread_string_len(plr->squad_filename, sizeof(plr->squad_filename), cfp);
	cfread_string_len(plr->current_campaign, sizeof(plr->current_campaign), cfp);
	cfread_string_len(plr->last_ship_flown, sizeof(plr->last_ship_flown), cfp);

	// controls
	plr_import_controls();

	// hud config
	plr_import_hud();

	// cutscenes, don't need it
	if (fver < 242) {
		cfread_int(cfp);
	}

	// volume stuff
	plr->sound_volume = cfread_float(cfp);
	plr->music_volume = cfread_float(cfp);
	plr->voice_volume = cfread_float(cfp);

	// detail settings
	plr_import_detail();

	// recent missions, don't need it
	int num_missions = cfread_int(cfp);

	for (idx = 0; idx < num_missions; idx++) {
		cfread_string_len(name, sizeof(name), cfp);
	}

	// stats, will skip if fver < 242
	plr_import_stats();

	plr->skill_level = cfread_int(cfp);

	if ( (plr->skill_level < 0) || (plr->skill_level > 4) ) {
		throw "Data check failure!";
	}

	// extra joystick stuff
	for (idx = 0; idx < 5; idx++) {
		plr->joy_axis_map_to[idx] = cfread_int(cfp);
		plr->joy_invert_axis[idx] = cfread_int(cfp);
	}

	// flags
	plr->save_flags = cfread_int(cfp);

	// loadout, will skip if fver < 242
	plr_import_loadout();

	// multiplayer
	plr_import_multiplayer();

	// two briefing related values
	plr->readyroom_listing_mode = cfread_int(cfp);
	Briefing_voice_enabled = cfread_int(cfp);

	plr->net_protocol = cfread_int(cfp);

	// protocol must be set to something
	if (plr->net_protocol == NET_NONE) {
		plr->net_protocol = NET_TCP;
	} else if ( (plr->net_protocol < 0) || (plr->net_protocol > NET_VMT) ) {
		throw "Data check failure!";
	}

	// red alert status, will skip if fver < 242 (and should be empty if multi)
	plr_import_red_alert();

	// briefing auto-advance
	plr->auto_advance = cfread_int(cfp);

	if ( (plr->auto_advance < 0) || (plr->auto_advance > 1) ) {
		throw "Data check failure!";
	}

	// some input options
	plr->Use_mouse_to_fly = cfread_int(cfp);
	plr->Mouse_sensitivity = cfread_int(cfp);
	plr->Joy_sensitivity = cfread_int(cfp);
	plr->Dead_zone_size = cfread_int(cfp);

	// variables
	plr_import_variables();


	// and... we're done! :)
}
Example #20
0
bool pilotfile::verify(const char *fname, int *rank)
{
    player t_plr;

    // set player ptr first thing
    p = &t_plr;

    filename = fname;

    if ( filename.size() == 4 ) {
        mprintf(("PLR => Invalid filename '%s'!\n", filename.c_str()));
        return false;
    }

    cfp = cfopen((char*)filename.c_str(), "rb", CFILE_NORMAL, CF_TYPE_PLAYERS);

    if ( !cfp ) {
        mprintf(("PLR => Unable to open '%s'!\n", filename.c_str()));
        return false;
    }

    unsigned int plr_id = cfread_uint(cfp);

    if (plr_id != PLR_FILE_ID) {
        mprintf(("PLR => Invalid header id for '%s'!\n", filename.c_str()));
        plr_close();
        return false;
    }

    // version, should be able to just ignore it
    ubyte plr_ver = cfread_ubyte(cfp);

    mprintf(("PLR => Verifying '%s' with version %d...\n", filename.c_str(), (int)plr_ver));

    // the point of all this: read in the PLR contents
    while ( !m_have_flags && !cfeof(cfp) ) {
        ushort section_id = cfread_ushort(cfp);
        uint section_size = cfread_uint(cfp);

        size_t start_pos = cftell(cfp);

        // safety, to help protect against long reads
        cf_set_max_read_len(cfp, section_size);

        try {
            switch (section_id) {
            case Section::Flags:
                mprintf(("PLR => Parsing:  Flags...\n"));
                m_have_flags = true;
                plr_read_flags();
                break;

            default:
                break;
            }
        } catch (cfile::max_read_length &msg) {
            // read to max section size, move to next section, discarding
            // extra/unknown data
            mprintf(("PLR => (0x%04x) %s\n", section_id, msg.what()));
        } catch (const char *err) {
            mprintf(("PLR => ERROR: %s\n", err));
            plr_close();
            return false;
        }

        // reset safety catch
        cf_set_max_read_len(cfp, 0);

        // skip to next section (if not already there)
        size_t offset_pos = (start_pos + section_size) - cftell(cfp);

        if (offset_pos) {
            mprintf(("PLR => Warning: (0x%04x) Short read, information may have been lost!\n", section_id));
            cfseek(cfp, offset_pos, CF_SEEK_CUR);
        }
    }

    if (rank) {
        *rank = p->stats.rank;
    }

    mprintf(("PLR => Verifying complete!\n"));

    // cleanup and return
    plr_close();

    return true;
}
void pilotfile_convert::csg_import_ships_weapons()
{
	index_list_t ilist;
	char name[35];
	int idx;
	int list_size = 0;

	int ship_count = cfread_int(cfp);
	int weap_count = cfread_int(cfp);

	for (idx = 0; idx < ship_count; idx++) {
		ubyte allowed = cfread_ubyte(cfp);
		csg->ships_allowed.push_back( (allowed != 0) );

		cfread_string_len(name, sizeof(name), cfp);

		ilist.name = name;
		ilist.index = ship_info_lookup(name);

		if (ilist.index < 0) {
			std::ostringstream error_msg;
			error_msg << "Data mismatch (ship lookup: " << ilist.name << ")!";
			throw std::runtime_error(error_msg.str().c_str());
		}

		csg->ship_list.push_back( ilist );
	}

	for (idx = 0; idx < weap_count; idx++) {
		ubyte allowed = cfread_ubyte(cfp);
		csg->weapons_allowed.push_back( allowed != 0 );

		cfread_string_len(name, sizeof(name), cfp);

		ilist.name = name;
		ilist.index = weapon_info_lookup(name);

		if (ilist.index < 0) {
			std::ostringstream error_msg;
			error_msg << "Data mismatch (weapon lookup: " << ilist.name << ")!";
			throw std::runtime_error(error_msg.str().c_str());
		}

		csg->weapon_list.push_back( ilist );
	}

	// get last ship flown index
	for (idx = 0; idx < ship_count; idx++) {
		if ( csg->ship_list[idx].name == plr->last_ship_flown ) {
			csg->last_ship_flown_index = idx;
			break;
		}
	}

	if (csg->last_ship_flown_index < 0) {
		std::ostringstream error_msg;
		error_msg << "Data mismatch (player ship: " << csg->last_ship_flown_index << ")!";
		throw std::runtime_error(error_msg.str().c_str());
	}

	// create list of medals (since it's missing from the old files)
	list_size = Num_medals;

	for (idx = 0; idx < list_size; idx++) {
		ilist.name = Medals[idx].name;
		ilist.index = idx;

		csg->medals_list.push_back( ilist );
	}

	// stuff intel list as well (present but burried in old files)
	list_size = Intel_info_size;

	for (idx = 0; idx < list_size; idx++) {
		ilist.name = Intel_info[idx].name;
		ilist.index = idx;

		csg->intel_list.push_back( ilist );
	}
}