void pilotfile::plr_write_flags() { startSection(Section::Flags); // tips cfwrite_ubyte((unsigned char)p->tips, cfp); // saved flags cfwrite_int(p->save_flags, cfp); // listing mode (single or campaign missions) cfwrite_int(p->readyroom_listing_mode, cfp); // briefing auto-play cfwrite_int(p->auto_advance, cfp); // special rank setting (to avoid having to read all stats on verify) // should be multi only from now on cfwrite_int(multi_stats.rank, cfp); // What game mode we were in last on this pilot cfwrite_int(p->player_was_multi, cfp); // which language was this pilot created with cfwrite_string_len(p->language, cfp); endSection(); }
void pilotfile_convert::plr_export_hud() { int idx; startSection(Section::HUD); // flags cfwrite_int(plr->hud_show_flags, cfp); cfwrite_int(plr->hud_show_flags2, cfp); cfwrite_int(plr->hud_popup_flags, cfp); cfwrite_int(plr->hud_popup_flags2, cfp); // settings cfwrite_ubyte(plr->hud_num_lines, cfp); cfwrite_int(plr->hud_rp_flags, cfp); cfwrite_int(plr->hud_rp_dist, cfp); // basic colors cfwrite_int(0, cfp); // color cfwrite_int(8, cfp); // alpha // gauge-specific colors cfwrite_int(39, cfp); for (idx = 0; idx < 39; idx++) { cfwrite_ubyte(plr->hud_colors[idx][0], cfp); cfwrite_ubyte(plr->hud_colors[idx][1], cfp); cfwrite_ubyte(plr->hud_colors[idx][2], cfp); cfwrite_ubyte(plr->hud_colors[idx][3], cfp); } endSection(); }
void pilotfile::plr_write_hud() { int idx; startSection(Section::HUD); // flags cfwrite_int(HUD_config.show_flags, cfp); cfwrite_int(HUD_config.show_flags2, cfp); cfwrite_int(HUD_config.popup_flags, cfp); cfwrite_int(HUD_config.popup_flags2, cfp); // settings cfwrite_ubyte(HUD_config.num_msg_window_lines, cfp); cfwrite_int(HUD_config.rp_flags, cfp); cfwrite_int(HUD_config.rp_dist, cfp); // basic colors cfwrite_int(HUD_config.main_color, cfp); cfwrite_int(HUD_color_alpha, cfp); // gauge-specific colors cfwrite_int(NUM_HUD_GAUGES, cfp); for (idx = 0; idx < NUM_HUD_GAUGES; idx++) { cfwrite_ubyte(HUD_config.clr[idx].red, cfp); cfwrite_ubyte(HUD_config.clr[idx].green, cfp); cfwrite_ubyte(HUD_config.clr[idx].blue, cfp); cfwrite_ubyte(HUD_config.clr[idx].alpha, cfp); } endSection(); }
void pilotfile_convert::plr_export_multiplayer() { startSection(Section::Multiplayer); // netgame options cfwrite_ubyte(plr->multi_squad_set, cfp); cfwrite_ubyte(plr->multi_endgame_set, cfp); cfwrite_int(plr->multi_flags, cfp); cfwrite_uint(plr->multi_respawn, cfp); cfwrite_ubyte(plr->multi_max_observers, cfp); cfwrite_ubyte(plr->multi_skill_level, cfp); cfwrite_ubyte(plr->multi_voice_qos, cfp); cfwrite_int(plr->multi_voice_token_wait, cfp); cfwrite_int(plr->multi_voice_record_time, cfp); cfwrite_int(plr->multi_time_limit, cfp); cfwrite_int(plr->multi_kill_limit, cfp); // local options cfwrite_int(plr->multi_local_flags, cfp); cfwrite_int(plr->multi_local_update_level, cfp); // netgame protocol cfwrite_int(plr->net_protocol, cfp); endSection(); }
void pilotfile::plr_write_multiplayer() { startSection(Section::Multiplayer); // netgame options cfwrite_ubyte(p->m_server_options.squad_set, cfp); cfwrite_ubyte(p->m_server_options.endgame_set, cfp); cfwrite_int(p->m_server_options.flags, cfp); cfwrite_uint(p->m_server_options.respawn, cfp); cfwrite_ubyte(p->m_server_options.max_observers, cfp); cfwrite_ubyte(p->m_server_options.skill_level, cfp); cfwrite_ubyte(p->m_server_options.voice_qos, cfp); cfwrite_int(p->m_server_options.voice_token_wait, cfp); cfwrite_int(p->m_server_options.voice_record_time, cfp); cfwrite_int((int)p->m_server_options.mission_time_limit, cfp); cfwrite_int(p->m_server_options.kill_limit, cfp); // local options cfwrite_int(p->m_local_options.flags, cfp); cfwrite_int(p->m_local_options.obj_update_level, cfp); // netgame protocol cfwrite_int(Multi_options_g.protocol, cfp); endSection(); }
void pilot::BinaryFileHandler::startArrayWrite(const char*, size_t size, bool short_index) { if (short_index) { cfwrite_ushort((short)size, _cfp); } else { cfwrite_int((int)size, _cfp); } }
void pilot::BinaryFileHandler::endSectionWrite() { Assertion(!_sectionOffsets.empty(), "No active section!"); auto previous_off = _sectionOffsets.back(); _sectionOffsets.pop_back(); if (previous_off.id == Section::Unnamed) { // ignore unnamed sections, these are only needed for JSON return; } size_t cur = (size_t) cftell(_cfp); Assert(cur >= previous_off.offset); size_t section_size = cur - previous_off.offset; if (section_size) { // go back to section size in file and write proper value cfseek(_cfp, (int) (cur - section_size - sizeof(int)), CF_SEEK_SET); cfwrite_int((int) section_size, _cfp); // go back to previous location for next section cfseek(_cfp, (int) cur, CF_SEEK_SET); } }
void pilotfile_convert::csg_export_loadout() { startSection(Section::Loadout); // base info cfwrite_string_len(csg->loadout.filename.c_str(), cfp); cfwrite_string_len(csg->loadout.last_modified.c_str(), cfp); // ship pool size_t list_size = csg->loadout.ship_pool.size(); for (size_t idx = 0; idx < list_size; idx++) { cfwrite_int(csg->loadout.ship_pool[idx], cfp); } // weapon pool list_size = csg->loadout.weapon_pool.size(); for (size_t idx = 0; idx < list_size; idx++) { cfwrite_int(csg->loadout.weapon_pool[idx], cfp); } // play ship loadout cfwrite_ushort(12, cfp); for (size_t idx = 0; idx < 12; idx++) { // ship cfwrite_int(csg->loadout.slot[idx].ship_index, cfp); // primary weapons cfwrite_int(3, cfp); for (size_t j = 0; j < 3; j++) { cfwrite_int(csg->loadout.slot[idx].wep[j], cfp); cfwrite_int(csg->loadout.slot[idx].wep_count[j], cfp); } // secondary weapons cfwrite_int(4, cfp); for (size_t j = 0; j < 4; j++) { cfwrite_int(csg->loadout.slot[idx].wep[j+3], cfp); cfwrite_int(csg->loadout.slot[idx].wep_count[j+3], cfp); } } endSection(); }
void pilotfile_convert::csg_export_variables() { int list_size = 0; int idx; startSection(Section::Variables); list_size = (int)csg->variables.size(); cfwrite_int(list_size, cfp); for (idx = 0; idx < list_size; idx++) { cfwrite_int(csg->variables[idx].type, cfp); cfwrite_string_len(csg->variables[idx].text, cfp); cfwrite_string_len(csg->variables[idx].variable_name, cfp); } endSection(); }
void pilotfile::csg_write_loadout() { int idx, j; startSection(Section::Loadout); // base info cfwrite_string_len(Player_loadout.filename, cfp); cfwrite_string_len(Player_loadout.last_modified, cfp); // ship pool for (idx = 0; idx < static_cast<int>(Ship_info.size()); idx++) { cfwrite_int(Player_loadout.ship_pool[idx], cfp); } // weapon pool for (idx = 0; idx < Num_weapon_types; idx++) { cfwrite_int(Player_loadout.weapon_pool[idx], cfp); } // play ship loadout cfwrite_ushort(MAX_WSS_SLOTS, cfp); for (idx = 0; idx < MAX_WSS_SLOTS; idx++) { wss_unit *slot = &Player_loadout.unit_data[idx]; // ship cfwrite_int(slot->ship_class, cfp); // primary weapons cfwrite_int(MAX_SHIP_PRIMARY_BANKS, cfp); for (j = 0; j < MAX_SHIP_PRIMARY_BANKS; j++) { cfwrite_int(slot->wep[j], cfp); cfwrite_int(slot->wep_count[j], cfp); } // secondary weapons cfwrite_int(MAX_SHIP_SECONDARY_BANKS, cfp); for (j = 0; j < MAX_SHIP_SECONDARY_BANKS; j++) { cfwrite_int(slot->wep[j+MAX_SHIP_PRIMARY_BANKS], cfp); cfwrite_int(slot->wep_count[j+MAX_SHIP_PRIMARY_BANKS], cfp); } } endSection(); }
void pilotfile::plr_write_variables() { int list_size = 0; int idx; startSection(Section::Variables); list_size = (int)p->variables.size(); cfwrite_int(list_size, cfp); for (idx = 0; idx < list_size; idx++) { cfwrite_int(p->variables[idx].type, cfp); cfwrite_string_len(p->variables[idx].text, cfp); cfwrite_string_len(p->variables[idx].variable_name, cfp); } endSection(); }
void pilotfile_convert::csg_export_flags() { startSection(Section::Flags); // tips cfwrite_ubyte((ubyte)plr->tips, cfp); // special rank cfwrite_int(csg->stats.rank, cfp); endSection(); }
void pilotfile::csg_write_flags() { startSection(Section::Flags); // tips cfwrite_ubyte((ubyte)p->tips, cfp); // avoid having to read everything to get the rank cfwrite_int(p->stats.rank, cfp); endSection(); }
void pilotfile::csg_write_stats() { int idx; startSection(Section::Scoring); // scoring stats cfwrite_int(p->stats.score, cfp); cfwrite_int(p->stats.rank, cfp); cfwrite_int(p->stats.assists, cfp); cfwrite_int(p->stats.kill_count, cfp); cfwrite_int(p->stats.kill_count_ok, cfp); cfwrite_int(p->stats.bonehead_kills, cfp); cfwrite_uint(p->stats.p_shots_fired, cfp); cfwrite_uint(p->stats.p_shots_hit, cfp); cfwrite_uint(p->stats.p_bonehead_hits, cfp); cfwrite_uint(p->stats.s_shots_fired, cfp); cfwrite_uint(p->stats.s_shots_hit, cfp); cfwrite_uint(p->stats.s_bonehead_hits, cfp); cfwrite_uint(p->stats.flight_time, cfp); cfwrite_uint(p->stats.missions_flown, cfp); cfwrite_int((int)p->stats.last_flown, cfp); cfwrite_int((int)p->stats.last_backup, cfp); // ship kills (scoring) for (idx = 0; idx < static_cast<int>(Ship_info.size()); idx++) { cfwrite_int(p->stats.kills[idx], cfp); } // medals earned (scoring) for (idx = 0; idx < Num_medals; idx++) { cfwrite_int(p->stats.medal_counts[idx], cfp); } endSection(); }
void pilotfile_convert::csg_export_stats() { startSection(Section::Scoring); // scoring stats cfwrite_int(csg->stats.score, cfp); cfwrite_int(csg->stats.rank, cfp); cfwrite_int(csg->stats.assists, cfp); cfwrite_int(csg->stats.kill_count, cfp); cfwrite_int(csg->stats.kill_count_ok, cfp); cfwrite_int(csg->stats.bonehead_kills, cfp); cfwrite_uint(csg->stats.p_shots_fired, cfp); cfwrite_uint(csg->stats.p_shots_hit, cfp); cfwrite_uint(csg->stats.p_bonehead_hits, cfp); cfwrite_uint(csg->stats.s_shots_fired, cfp); cfwrite_uint(csg->stats.s_shots_hit, cfp); cfwrite_uint(csg->stats.s_bonehead_hits, cfp); cfwrite_uint(csg->stats.flight_time, cfp); cfwrite_uint(csg->stats.missions_flown, cfp); cfwrite_int((int)csg->stats.last_flown, cfp); cfwrite_int((int)csg->stats.last_backup, cfp); // ship kills (scoring) size_t list_size = csg->stats.ship_kills.size(); for (size_t idx = 0; idx < list_size; idx++) { cfwrite_int(csg->stats.ship_kills[idx].val, cfp); } // medals earned (scoring) list_size = csg->stats.medals_earned.size(); for (size_t idx = 0; idx < list_size; idx++) { cfwrite_int(csg->stats.medals_earned[idx].val, cfp); } endSection(); }
void pilotfile::csg_write_lastmissions() { int i; startSection(Section::LastMissions); // store list of most recently played missions cfwrite_int(Num_recent_missions, cfp); for (i=0; i<Num_recent_missions; i++) { cfwrite_string_len(Recent_missions[i], cfp); } endSection(); }
void pilotfile::startSection(Section::id section_id) { Assert( cfp ); const int zero = 0; cfwrite_ushort( (ushort)section_id, cfp ); // to be updated when endSection() is called cfwrite_int(zero, cfp); // starting offset, for size of section m_size_offset = cftell(cfp); }
void pilot::BinaryFileHandler::startSectionWrite(Section id) { if (id == Section::Unnamed) { _sectionOffsets.push_back({id, 0}); return; } cfwrite_ushort((ushort) id, _cfp); // to be updated when endSection() is called cfwrite_int(0, _cfp); // starting offset, for size of section _sectionOffsets.push_back({id, (size_t)cftell(_cfp)}); }
void pilotfile_convert::plr_export_controls() { unsigned int idx; startSection(Section::Controls); cfwrite_ushort((unsigned short)plr->controls.size(), cfp); for (idx = 0; idx < plr->controls.size(); idx++) { cfwrite_short(plr->controls[idx].key_id, cfp); cfwrite_short(plr->controls[idx].joy_id, cfp); // placeholder? for future mouse_id? cfwrite_short(-1, cfp); } // extra joystick stuff cfwrite_int(MAX_JOY_AXES_CONV, cfp); for (idx = 0; idx < MAX_JOY_AXES_CONV; idx++) { cfwrite_int(plr->joy_axis_map_to[idx], cfp); cfwrite_int(plr->joy_invert_axis[idx], cfp); } endSection(); }
void pilotfile::plr_write_controls() { int idx; startSection(Section::Controls); cfwrite_ushort(CCFG_MAX, cfp); for (idx = 0; idx < CCFG_MAX; idx++) { cfwrite_short(Control_config[idx].key_id, cfp); cfwrite_short(Control_config[idx].joy_id, cfp); // placeholder? for future mouse_id? cfwrite_short(-1, cfp); } cfwrite_int(NUM_JOY_AXIS_ACTIONS, cfp); for (idx = 0; idx < NUM_JOY_AXIS_ACTIONS; idx++) { cfwrite_int(Axis_map_to[idx], cfp); cfwrite_int(Invert_axis[idx], cfp); } endSection(); }
void pilotfile::csg_write_variables() { int idx; startSection(Section::Variables); cfwrite_int(Campaign.num_variables, cfp); for (idx = 0; idx < Campaign.num_variables; idx++) { cfwrite_int(Campaign.variables[idx].type, cfp); cfwrite_string_len(Campaign.variables[idx].text, cfp); cfwrite_string_len(Campaign.variables[idx].variable_name, cfp); } cfwrite_int(Campaign.redalert_num_variables, cfp); for (idx = 0; idx < Campaign.redalert_num_variables; idx++) { cfwrite_int(Campaign.redalert_variables[idx].type, cfp); cfwrite_string_len(Campaign.redalert_variables[idx].text, cfp); cfwrite_string_len(Campaign.redalert_variables[idx].variable_name, cfp); } endSection(); }
void pilotfile_convert::plr_export_flags() { startSection(Section::Flags); // tips cfwrite_ubyte((unsigned char)plr->tips, cfp); // saved flags cfwrite_int(plr->save_flags, cfp); // listing mode (single or campaign missions) cfwrite_int(plr->readyroom_listing_mode, cfp); // briefing auto-play cfwrite_int(plr->auto_advance, cfp); // special rank setting (to avoid having to read all stats on verify) cfwrite_int(plr->rank, cfp); // What game mode we were in last on this pilot cfwrite_int(plr->is_multi, cfp); endSection(); }
void pilotfile::endSection() { Assert( cfp ); Assert( m_size_offset > 0 ); size_t cur = cftell(cfp); Assert( cur >= m_size_offset ); size_t section_size = cur - m_size_offset; if (section_size) { // go back to section size in file and write proper value cfseek(cfp, cur - section_size - sizeof(int), CF_SEEK_SET); cfwrite_int((int)section_size, cfp); // go back to previous location for next section cfseek(cfp, cur, CF_SEEK_SET); } }
void pilotfile_convert::plr_export() { Assert( cfp != NULL ); // header and version cfwrite_int(PLR_FILE_ID, cfp); cfwrite_ubyte(PLR_VERSION, cfp); // flags and info sections go first plr_export_flags(); plr_export_info(); // everything else is next, not order specific plr_export_stats(); plr_export_stats_multi(); plr_export_hud(); plr_export_variables(); plr_export_multiplayer(); plr_export_controls(); plr_export_settings(); // and... we're done! :) }
void pilotfile_convert::csg_export() { Assert( cfp != NULL ); // header and version cfwrite_int(CSG_FILE_ID, cfp); cfwrite_ubyte(CSG_VERSION, cfp); // flags and info sections go first csg_export_flags(); csg_export_info(); // everything else is next, not order specific csg_export_missions(); csg_export_techroom(); csg_export_loadout(); csg_export_stats(); csg_export_redalert(); csg_export_hud(); csg_export_variables(); csg_export_cutscenes(); // and... we're done! :) }
void pilotfile::csg_write_settings() { startSection(Section::Settings); // sound/voice/music cfwrite_float(Master_sound_volume, cfp); cfwrite_float(Master_event_music_volume, cfp); cfwrite_float(Master_voice_volume, cfp); cfwrite_int(Briefing_voice_enabled, cfp); // skill level cfwrite_int(Game_skill_level, cfp); // input options cfwrite_int(Use_mouse_to_fly, cfp); cfwrite_int(Mouse_sensitivity, cfp); cfwrite_int(Joy_sensitivity, cfp); cfwrite_int(Joy_dead_zone_size, cfp); endSection(); }
bool pilotfile::save_player(player *_p) { // never save a pilot file for the standalone server in multiplayer if ( (Game_mode & GM_MULTIPLAYER) && (Game_mode & GM_STANDALONE_SERVER) ) { return false; } // set player ptr first thing p = _p; if ( !p ) { Assert( (Player_num >= 0) && (Player_num < MAX_PLAYERS) ); p = &Players[Player_num]; } if ( !strlen(p->callsign) ) { return false; } filename = p->callsign; filename += ".plr"; if ( filename.size() == 4 ) { mprintf(("PLR => Invalid filename '%s'!\n", filename.c_str())); return false; } // open it, hopefully... cfp = cfopen((char*)filename.c_str(), "wb", CFILE_NORMAL, CF_TYPE_PLAYERS); if ( !cfp ) { mprintf(("PLR => Unable to open '%s' for saving!\n", filename.c_str())); return false; } // header and version cfwrite_int(PLR_FILE_ID, cfp); cfwrite_ubyte(PLR_VERSION, cfp); mprintf(("PLR => Saving '%s' with version %d...\n", filename.c_str(), (int)PLR_VERSION)); // flags and info sections go first mprintf(("PLR => Saving: Flags...\n")); plr_write_flags(); mprintf(("PLR => Saving: Info...\n")); plr_write_info(); // everything else is next, not order specific mprintf(("PLR => Saving: Scoring...\n")); plr_write_stats(); mprintf(("PLR => Saving: ScoringMulti...\n")); plr_write_stats_multi(); mprintf(("PLR => Saving: HUD...\n")); plr_write_hud(); mprintf(("PLR => Saving: Variables...\n")); plr_write_variables(); mprintf(("PLR => Saving: Multiplayer...\n")); plr_write_multiplayer(); mprintf(("PLR => Saving: Controls...\n")); plr_write_controls(); mprintf(("PLR => Saving: Settings...\n")); plr_write_settings(); // Done! mprintf(("PLR => Saving complete!\n")); plr_close(); return true; }
void pilotfile::plr_write_settings() { startSection(Section::Settings); // sound/voice/music cfwrite_float(Master_sound_volume, cfp); cfwrite_float(Master_event_music_volume, cfp); cfwrite_float(Master_voice_volume, cfp); cfwrite_int(Briefing_voice_enabled, cfp); // skill level cfwrite_int(Game_skill_level, cfp); // input options cfwrite_int(Use_mouse_to_fly, cfp); cfwrite_int(Mouse_sensitivity, cfp); cfwrite_int(Joy_sensitivity, cfp); cfwrite_int(Dead_zone_size, cfp); // detail cfwrite_int(Detail.setting, cfp); cfwrite_int(Detail.nebula_detail, cfp); cfwrite_int(Detail.detail_distance, cfp); cfwrite_int(Detail.hardware_textures, cfp); cfwrite_int(Detail.num_small_debris, cfp); cfwrite_int(Detail.num_particles, cfp); cfwrite_int(Detail.num_stars, cfp); cfwrite_int(Detail.shield_effects, cfp); cfwrite_int(Detail.lighting, cfp); cfwrite_int(Detail.targetview_model, cfp); cfwrite_int(Detail.planets_suns, cfp); cfwrite_int(Detail.weapon_extras, cfp); endSection(); }
void pilotfile::plr_write_stats_multi() { int idx, list_size = 0; startSection(Section::ScoringMulti); // global, all-time stats cfwrite_int(multi_stats.score, cfp); cfwrite_int(multi_stats.rank, cfp); cfwrite_int(multi_stats.assists, cfp); cfwrite_int(multi_stats.kill_count, cfp); cfwrite_int(multi_stats.kill_count_ok, cfp); cfwrite_int(multi_stats.bonehead_kills, cfp); cfwrite_uint(multi_stats.p_shots_fired, cfp); cfwrite_uint(multi_stats.p_shots_hit, cfp); cfwrite_uint(multi_stats.p_bonehead_hits, cfp); cfwrite_uint(multi_stats.s_shots_fired, cfp); cfwrite_uint(multi_stats.s_shots_hit, cfp); cfwrite_uint(multi_stats.s_bonehead_hits, cfp); cfwrite_uint(multi_stats.flight_time, cfp); cfwrite_uint(multi_stats.missions_flown, cfp); cfwrite_int((int)multi_stats.last_flown, cfp); cfwrite_int((int)multi_stats.last_backup, cfp); // ship kills (contains medals across all mods, not just current) list_size = (int)multi_stats.ship_kills.size(); cfwrite_int(list_size, cfp); for (idx = 0; idx < list_size; idx++) { cfwrite_string_len(multi_stats.ship_kills[idx].name.c_str(), cfp); cfwrite_int(multi_stats.ship_kills[idx].val, cfp); } // medals earned (contains medals across all mods, not just current) list_size = (int)multi_stats.medals_earned.size(); cfwrite_int(list_size, cfp); for (idx = 0; idx < list_size; idx++) { cfwrite_string_len(multi_stats.medals_earned[idx].name.c_str(), cfp); cfwrite_int(multi_stats.medals_earned[idx].val, cfp); } endSection(); }
void pilotfile::csg_write_redalert() { int idx, j, list_size = 0; int count; red_alert_ship_status *ras; startSection(Section::RedAlert); list_size = (int)Red_alert_wingman_status.size(); cfwrite_int(list_size, cfp); if (list_size) { cfwrite_string_len(Red_alert_precursor_mission.c_str(), cfp); for (idx = 0; idx < list_size; idx++) { ras = &Red_alert_wingman_status[idx]; cfwrite_string_len(ras->name.c_str(), cfp); cfwrite_float(ras->hull, cfp); // ship class, should be index into ship_list[] on load cfwrite_int(ras->ship_class, cfp); // subsystem hits count = (int)ras->subsys_current_hits.size(); cfwrite_int(count, cfp); for (j = 0; j < count; j++) { cfwrite_float(ras->subsys_current_hits[j], cfp); } // subsystem aggregate hits count = (int)ras->subsys_aggregate_current_hits.size(); cfwrite_int(count, cfp); for (j = 0; j < count; j++) { cfwrite_float(ras->subsys_aggregate_current_hits[j], cfp); } // primary weapon loadout and status count = (int)ras->primary_weapons.size(); cfwrite_int(count, cfp); for (j = 0; j < count; j++) { cfwrite_int(ras->primary_weapons[j].index, cfp); cfwrite_int(ras->primary_weapons[j].count, cfp); } // secondary weapon loadout and status count = (int)ras->secondary_weapons.size(); cfwrite_int(count, cfp); for (j = 0; j < count; j++) { cfwrite_int(ras->secondary_weapons[j].index, cfp); cfwrite_int(ras->secondary_weapons[j].count, cfp); } } } endSection(); }