/* * Copyright (C) Volition, Inc. 1999. All rights reserved. * * All source code herein is the property of Volition, Inc. You may not sell * or otherwise commercially exploit the source or things you created based on the * source. * */ /* * $Logfile: /Freespace2/code/Fred2/FREDDoc.cpp $ * $Revision: 1.10 $ * $Date: 2006-10-08 08:04:52 $ * $Author: Goober5000 $ * * FREDDoc.cpp : implementation of the CFREDDoc class * Document class for document/view architechure, which we don't really use in * Fred, but MFC forces you do use like it or not. Handles loading/saving * mainly. Most of the MFC related stuff is handled in FredView. * * $Log: not supported by cvs2svn $ * Revision 1.9 2006/10/08 05:21:44 Goober5000 * nitpick * * Revision 1.8 2006/10/01 00:53:58 Goober5000 * fix crlf * * Revision 1.7 2006/07/10 21:48:33 taylor * fix undo system * restore the two autosave points that got removed for some reason (yes, these are needed for things to work properly) * * Revision 1.6 2006/02/11 02:58:23 Goober5000 * yet more various and sundry fixes * --Goober5000 * * Revision 1.5 2006/02/11 00:13:55 Goober5000 * more FS1 import goodness * --Goober5000 * * Revision 1.4 2006/01/31 04:13:00 Goober5000 * oh noes! :( * * Revision 1.3 2006/01/31 01:53:36 Goober5000 * update FSM import for FSPort v3.0 * --Goober5000 * * Revision 1.2 2006/01/30 06:27:59 taylor * dynamic starfield bitmaps * * Revision 1.1 2006/01/19 02:27:31 Goober5000 * import FRED2 back into fs2_open module * --Goober5000 * * Revision 1.12 2005/10/29 23:02:33 Goober5000 * partial FRED commit of changes * --Goober5000 * * Revision 1.11 2005/03/29 03:43:11 phreak * ai directory fixes as well as fixes for the new jump node code * * Revision 1.10 2005/03/21 00:29:25 phreak * make sure the starfield bitmaps are generated upon mission load * * Revision 1.9 2004/07/29 00:18:42 Kazan * taylor and I fixed fred2 by making code.lib and fred2's defines match up * * Revision 1.8 2004/05/02 18:03:19 randomtiger * Fred doesnt need subspace palette any more * * Revision 1.7 2004/04/03 18:06:35 Kazan * Fixes: * * Revision 1.6 2003/10/06 06:25:10 Goober5000 * added confirmation messages when no errors are detected on import * --Goober5000 * * Revision 1.5 2003/09/30 04:05:08 Goober5000 * updated FRED to import FS1 default weapons loadouts as well as missions * --Goober5000 * * Revision 1.4 2003/09/28 21:22:58 Goober5000 * added the option to import FSM missions, added a replace function, spruced * up my $player, $rank, etc. code, and fixed encrypt being misspelled as 'encrpyt' * --Goober5000 * * Revision 1.3 2003/01/03 03:12:53 Goober5000 * updated obselete code for upcoming stuff, just in case it's ever used again :) * --Goober5000 * * Revision 1.2 2002/08/15 01:06:34 penguin * Include filename reorg (to coordinate w/ fs2_open) * * Revision 1.1.1.1 2002/07/15 03:10:57 inquisitor * Initial FRED2 Checking * * * 7 7/23/99 2:12p Jamesa * fix gamepalette request * * 6 5/20/99 6:59p Dave * Added alternate type names for ships. Changed swarm missile table * entries. * * 5 10/29/98 6:49p Dave * Finished up Fred support for externalizing mission and campaign files. * * 4 10/29/98 12:50p Dave * Intermediate checkin for fred hash table stuff. * * 3 10/28/98 11:30a Dave * Temporary checkin. * * 2 10/07/98 6:28p Dave * Initial checkin. Renamed all relevant stuff to be Fred2 instead of * Fred. Globalized mission and campaign file extensions. Removed Silent * Threat specific code. * * 1 10/07/98 3:00p Dave * * 94 9/21/98 8:46p Dave * Put in special check in fred for identifying unknown ships. * * 93 9/16/98 6:54p Dave * Upped max sexpression nodes to 1800 (from 1600). Changed FRED to sort * the ship list box. Added code so that tracker stats are not stored with * only 1 player. * * 92 8/13/98 9:53a Hoffoss * Fixed bug where loading mission doesn't update palette used for that * mission. * * 91 4/30/98 8:23p John * Fixed some bugs with Fred caused by my new cfile code. * * 90 4/28/98 2:13p Hoffoss * Added code to help keep invalid player ship types from existing in * mission. * * 89 4/10/98 10:22p Mike * Fix bug in parsing medals.tbl. * * 88 4/10/98 4:51p Hoffoss * Made several changes related to tooltips. * * 87 3/25/98 4:14p Hoffoss * Split ship editor up into ship editor and a misc dialog, which tracks * flags and such. * * 86 3/10/98 4:26p Hoffoss * Changed jump node structure to include a name. Position is now taken * from the object (each jump node has an associated object now). * * 85 2/26/98 4:59p Allender * groundwork for team vs team briefings. Moved weaponry pool into the * Team_data structure. Added team field into the p_info structure. * Allow for mutliple structures in the briefing code. * * 84 1/28/98 11:00a Johnson * Fixed parse code for medals table (new field) * * 83 11/06/97 4:37p Allender * a ton of medal work. Removed an uneeded element in the scoring * structure. Fix up medals screen to apprioriate display medals (after * mask was changed). Fix Fred to only display medals which may actually * be granted. Added image_filename to player struct for Jason Hoffoss * * 82 11/05/97 10:19p Mike * Comment out call to parse_medal_tbl() to allow Fred to run. * * 81 11/05/97 4:43p Allender * reworked medal/rank system to read all data from tables. Made Fred * read medals.tbl. Changed ai-warp to ai-warp-out which doesn't require * waypoint for activation * * 80 11/04/97 4:50p Hoffoss * Made mission loading failure display an error message stating so. * * 79 11/04/97 4:33p Hoffoss * Made saving keep the current briefing state intact. * * 78 10/20/97 1:20p Hoffoss * Fixed bug loading mission file after a save. * * 77 10/19/97 11:36p Hoffoss * Made mission saving call reload the mission after saving it to verify * it was written error free. * * 76 10/08/97 11:47a Hoffoss * Added better fred handling of Weaponry_pool. * * 75 9/20/97 8:16a John * Made .clr files go into the Cache directory. Replaced cfopen(name,NULL) * to delete a file with cf_delete. * * 74 9/18/97 11:52a Johnson * Fixed bug with player starts count being incorrect. * * 73 9/17/97 11:58a Hoffoss * Fixed mission load code to properly set arrival cues to player ships. * * 72 9/17/97 10:32a Allender * fixup references to old "Player" ship to new real shipname * * 71 9/16/97 9:41p Hoffoss * Changed Fred code around to stop using Parse_player structure for * player information, and use actual ships instead. * * 70 9/09/97 6:50p Hoffoss * Fixed bug with mission saving. * * 69 9/09/97 1:55p Hoffoss * Fixed bug with saving missions that are readonly. * * 68 8/21/97 1:49p Hoffoss * Fixed bugs with loading files. Wasn't clearing the last mission first, * and multiplayer starts in a mission caused it to think it was modified * right away. * * 67 8/20/97 5:45p Hoffoss * Fixed bugs with mission name in sexp in non campaign mode in Fred. * * 66 8/20/97 4:03p Hoffoss * Fixed bug in reload current mission (revert). * * 65 8/17/97 10:22p Hoffoss * Fixed several bugs in Fred with Undo feature. In the process, recoded * a lot of CFile.cpp. * * 64 8/16/97 9:24p Hoffoss * Added support for team of players in multiplayer. * * 63 8/16/97 6:44p Hoffoss * Changes to allow any player to be in a wing. * * 62 8/16/97 3:53p Hoffoss * Added OF_NO_SHIELDS define and support in Fred and mission load/save. * * 61 8/13/97 5:49p Hoffoss * Fixed bugs, made additions. * * 60 8/13/97 12:46p Hoffoss * Added campaign error checker, accelerator table, and mission goal data * listings to sexp tree right click menu. * * 59 8/12/97 1:55a Hoffoss * Made extensive changes to object reference checking and handling for * object deletion call. * * 58 7/31/97 5:55p John * made so you pass flags to obj_create. * Added new collision code that ignores any pairs that will never * collide. * * 57 7/30/97 2:10p Hoffoss * Made new missions that have never been saved yet save backups. * * 56 7/28/97 3:50p Hoffoss * Added global error checker call to mission load and save. * * 55 7/10/97 2:32p Hoffoss * Made message editor dialog box modeless. * * 54 7/08/97 11:35a Hoffoss * Fixed bug in initial orders, and also redid how shields are handled by * Fred. * * 53 6/26/97 5:18p Hoffoss * Major rework of briefing editor functionality. * * 52 6/24/97 10:22a Hoffoss * Added a forced update for briefing info prior to a mission save. * * 51 6/19/97 11:34a Hoffoss * Fixed bug in auto mission convertion. * * 50 6/18/97 3:25p Hoffoss * Added autoconverting of old ship names (for ships in wings) at mission * load time, and added an hourglass cursor change when autosaving. * * 49 6/17/97 11:07a Hoffoss * Fixed a few bugs: revert doesn't reset mission first, and sexp tree * copy doesn't act act as a single chain. * * 48 6/11/97 10:02a Comet * fixed a bug. * * 47 6/09/97 4:57p Hoffoss * Added autosave and undo to Fred. * * 46 6/05/97 6:10p Hoffoss * Added features: Autosaving, object hiding. Also fixed some minor bugs. * * 45 5/23/97 3:18p Hoffoss * Event editor made modeless. * * 44 5/21/97 5:42p Hoffoss * Added features requested on Todo list. * * 43 5/01/97 4:14p Hoffoss * Viewer position saved to missions now for Fred restoration of state. * * 42 4/25/97 3:53p Hoffoss * Fixed bug in weapons save/load and moved weapon look up function to * weapons.cpp. * * 41 4/25/97 3:28p Mike * Making shield multi-part. * * 40 4/21/97 5:02p Hoffoss * Player/player status editing supported, and both saved and loaded from * Mission files. * * 39 3/20/97 3:55p Hoffoss * Major changes to how dialog boxes initialize (load) and update (save) * their internal data. This should simplify things and create less * problems. * * 38 3/04/97 6:27p Hoffoss * Changes to Fred to handle new wing structure. * * 37 2/28/97 11:31a Hoffoss * Implemented modeless dialog saving and restoring, and changed some * variables names. * * 36 2/27/97 3:09p Allender * major wing structure enhancement. simplified wing code. All around * better wing support * * 35 2/20/97 4:03p Hoffoss * Several ToDo items: new reinforcement clears arrival cue, reinforcement * control from ship and wing dialogs, show grid toggle. * * 34 2/17/97 5:28p Hoffoss * Checked RCS headers, added them were missing, changing description to * something better, etc where needed. * * 14 2/12/97 12:25p Hoffoss * Expanded on global error checker, added initial orders conflict * checking and warning, added waypoint editor dialog and code. * * 13 1/30/97 2:24p Hoffoss * Added remaining mission file structures and implemented load/save of * them. * * $NoKeywords: $ */ #include #include "stdafx.h" #include "FRED.h" #include #include "FREDDoc.h" #include "FREDView.h" #include "PrefsDlg.h" #include "render/3d.h" #include "object/object.h" #include "editor.h" #include "ai/ai.h" #include "ai/ailocal.h" #include "cfile/cfile.h" #include "cfile/cfilesystem.h" #include "ship/ship.h" #include "mission/missionparse.h" #include "mission/missiongoals.h" #include "MissionSave.h" #include "weapon/weapon.h" #include "Management.h" #include "globalincs/linklist.h" #include "FredRender.h" #include "MainFrm.h" #include "EventEditor.h" #include "ai/aigoals.h" #include "MessageEditorDlg.h" #include "palman/palman.h" #include "localization/fhash.h" #include "cmdline/cmdline.h" #include "starfield/starfield.h" extern int num_objects; #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif // In editor mode, use class CFile, in game, use CFILE (our file) #define XFILE CFile // stupid #ifndef __FOLDERDLG_H__ #include "FolderDlg.h" #endif ///////////////////////////////////////////////////////////////////////////// // CFREDDoc IMPLEMENT_DYNCREATE(CFREDDoc, CDocument) BEGIN_MESSAGE_MAP(CFREDDoc, CDocument) //{{AFX_MSG_MAP(CFREDDoc) ON_COMMAND(ID_EDIT_DELETE, OnEditDelete) ON_COMMAND(ID_DUPLICATE, OnDuplicate) ON_COMMAND(ID_EDIT_COPY, OnEditCopy) ON_COMMAND(ID_EDIT_CUT, OnEditCut) ON_COMMAND(ID_EDIT_HOLD, OnEditHold) ON_COMMAND(ID_EDIT_FETCH, OnEditFetch) ON_COMMAND(ID_EDIT_PASTE, OnEditPaste) ON_COMMAND(ID_EDIT_UNDO, OnEditUndo) ON_COMMAND(ID_FILE_PREFERENCES, OnFilePreferences) ON_COMMAND(ID_FILE_IMPORT_FSM, OnFileImportFSM) ON_COMMAND(ID_FILE_IMPORT_WEAPONS, OnFileImportWeapons) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CFREDDoc construction/destruction // Global pointer to the FREDDoc class. // Used by MK to, among other things, I hope, update the modified flag from // outside the FREDDoc class. CFREDDoc *FREDDoc_ptr = NULL; int Local_modified = 0; int Undo_available = 0; int Undo_count = 0; extern int Fred_found_unknown_ship_during_parsing; CFREDDoc::CFREDDoc() { int i; FREDDoc_ptr = this; confirm_deleting = TRUE; show_capital_ships = TRUE; show_elevations = TRUE; show_fighters = TRUE; show_grid = TRUE; show_misc_objects = TRUE; show_planets = TRUE; show_waypoints = TRUE; show_starfield = TRUE; for (i=0; iicon_select(-1); // clean things up first len = strlen(mission_pathname); strcpy(name, mission_pathname); if (name[len - 4] == '.') len -= 4; name[len] = 0; // drop extension i = len; while (i--) if ((name[i] == '\\') || (name[i] == ':')) break; strcpy(Mission_filename, name + i + 1); // for (i=1; i<=BACKUP_DEPTH; i++) { // sprintf(name + len, ".%.3d", i); // unlink(name); // } if (load_mission(mission_pathname)) { *Mission_filename = 0; return FALSE; } Fred_view_wnd->global_error_check(); autosave("nothing"); Undo_count = 0; return TRUE; } // save mission to a file BOOL CFREDDoc::OnSaveDocument(LPCTSTR pathname) { CFred_mission_save save; char name[1024]; int len; DWORD attrib; FILE *fp; len = strlen(pathname); strcpy(name, pathname); if (name[len - 4] == '.') len -= 4; name[len] = 0; // drop extension while (len--) if ((name[len] == '\\') || (name[len] == ':')) break; strcpy(Mission_filename, name + len + 1); Fred_view_wnd->global_error_check(); if (Briefing_dialog) { Briefing_dialog->update_data(1); Briefing_dialog->save_editor_state(); } if (Event_editor_dlg) Fred_main_wnd->MessageBox("Event editor dialog is still open, so changes there won't be saved"); if (Message_editor_dlg) Fred_main_wnd->MessageBox("Message editor dialog is still open, so changes there won't be saved"); fp = fopen(pathname, "r"); if (fp) { fclose(fp); attrib = GetFileAttributes(pathname); if (attrib & FILE_ATTRIBUTE_READONLY) { Fred_main_wnd->MessageBox("File is read-only. You need to check it out before saving to it"); return FALSE; } } if (save.save_mission_file((char *) pathname)) { Fred_main_wnd->MessageBox("An error occured while saving!", NULL, MB_OK | MB_ICONEXCLAMATION); return FALSE; } SetModifiedFlag(FALSE); if (load_mission((char *) pathname)) Error(LOCATION, "Failed attempting to reload mission after saving. Report this bug now!"); if (Briefing_dialog) { Briefing_dialog->restore_editor_state(); Briefing_dialog->update_data(1); } return TRUE; // return CDocument::OnSaveDocument(pathname); } int CFREDDoc::check_undo() { char name[256]; FILE *fp; Undo_available = 0; if (!Undo_count) return 0; cf_create_default_path_string(name, sizeof(name) - 1, CF_TYPE_MISSIONS); SAFE_STRCAT(name, MISSION_BACKUP_NAME, (sizeof(name) - 1)); SAFE_STRCAT(name, ".002", (sizeof(name) - 1)); fp = fopen(name, "r"); if (!fp) return 0; fclose(fp); Undo_available = 1; return 1; } int CFREDDoc::autosave(char *desc) { int i; CFred_mission_save save; CWaitCursor wait; if (Autosave_disabled) return 0; if (Briefing_dialog) Briefing_dialog->update_data(1); if (save.autosave_mission_file(MISSION_BACKUP_NAME)) { Undo_count = Undo_available = 0; return -1; } for (i=BACKUP_DEPTH; i>1; i--) undo_desc[i] = undo_desc[i - 1]; if (desc) undo_desc[1] = desc; else undo_desc[1].Empty(); Undo_count++; check_undo(); return 0; } int CFREDDoc::autoload() { char name[256], backup_name[256]; int i, r, len; FILE *fp; cf_create_default_path_string(name, sizeof(name) - 1, CF_TYPE_MISSIONS); SAFE_STRCAT(name, MISSION_BACKUP_NAME, (sizeof(name) - 1)); SAFE_STRCAT(name, ".002", (sizeof(name) - 1)); fp = fopen(name, "r"); if (!fp) return 0; fclose(fp); if (Briefing_dialog) Briefing_dialog->icon_select(-1); // clean things up first // editor_init_mission(); r = load_mission(name); Update_window = 1; strcpy(backup_name, MISSION_BACKUP_NAME); len = strlen(backup_name); strcat(backup_name, ".001"); cf_delete(backup_name, CF_TYPE_MISSIONS); for (i=1; iMessageBox(name); } else { sprintf(name, "Unable to load the file \"%s\".", pathname); Fred_view_wnd->MessageBox(name); } create_new_mission(); return -1; } if(Fred_found_unknown_ship_during_parsing) { if (flags & MPF_IMPORT_FSM) { char msg[256]; sprintf(msg, "Fred encountered unknown ship/weapon classes when importing \"%s\" (path \"%s\"). You will have to manually edit the converted mission to correct this.", The_mission.name, pathname); Fred_view_wnd->MessageBox(msg); } else { Fred_view_wnd->MessageBox("Fred encountered unknown ship/weapon classes when parsing the mission file. This may be due to mission disk data you do not have."); } } Fred_found_unknown_ship_during_parsing = 0; for (i=0; icount; j++){ ob = obj_create(OBJ_WAYPOINT, -1, i * 65536 + j, NULL, &wptr->waypoints[j], 0.0f, OF_RENDERS); } } obj_merge_created_list(); objp = GET_FIRST(&obj_used_list); while (objp != END_OF_LIST(&obj_used_list)) { if (objp->flags & OF_PLAYER_SHIP) { Assert(objp->type == OBJ_SHIP); objp->type = OBJ_START; // Player_starts++; } objp = GET_NEXT(objp); } for (i=0; i= 0); Assert(Mission_palette <= 98); // RT, dont need this anymore #if 0 if (The_mission.flags & MISSION_FLAG_SUBSPACE) { strcpy(name, NOX("gamepalette-subspace")); } else { strcpy(name, "gamepalette1-01"); // sprintf(name, NOX("gamepalette1-%02d"), Mission_palette + 1); } palette_load_table(name); #endif // go through all ships and translate their alternate name indices objp = GET_FIRST(&obj_used_list); while (objp != END_OF_LIST(&obj_used_list)) { // if this is a ship, check it, and mark its possible alternate name down in the auxiliary array if(((objp->type == OBJ_SHIP) || (objp->type == OBJ_START)) && (objp->instance >= 0) && (Ships[objp->instance].alt_type_index >= 0)){ mission_parse_lookup_alt_index(Ships[objp->instance].alt_type_index, Fred_alt_names[objp->instance]); // also zero it Ships[objp->instance].alt_type_index = -1; } objp = GET_NEXT(objp); } view_pos = Parse_viewer_pos; view_orient = Parse_viewer_orient; set_modified(0); stars_post_level_init(); return 0; } // Editor-level interface to mission load/save. // Does nothing now.. Handled by OnOpenDocument and OnSaveDocument. This is because we // want to avoid using the CArchive for file I/O -JH void CFREDDoc::Serialize(CArchive& ar) { return; /* The original Serialize code int rw_flag; XFILE *fp; // CString CSfilename; // char filename[128], *tfilename; fp = ar.GetFile(); rw_flag = ar.IsStoring(); // CSfilename = fp->GetFileName(); // tfilename = CSfilename.GetBuffer(16); // strcpy(filename, tfilename); // CSfilename.ReleaseBuffer(); // -- Don't close this, it gets closed by MFC -- ar.Close(); cfile_serialize(fp, rw_flag); cfile_serialize_editor(fp, rw_flag); */ } ///////////////////////////////////////////////////////////////////////////// // CFREDDoc diagnostics #ifdef _DEBUG void CFREDDoc::AssertValid() const { CDocument::AssertValid(); } void CFREDDoc::Dump(CDumpContext& dc) const { CDocument::Dump(dc); } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CFREDDoc commands void CFREDDoc::OnEditDelete() { // TODO: Add your command handler code here } void CFREDDoc::OnDuplicate() { // TODO: Add your command handler code here } void CFREDDoc::OnEditCopy() { // TODO: Add your command handler code here } void CFREDDoc::OnEditCut() { // TODO: Add your command handler code here } void CFREDDoc::OnEditPaste() { // TODO: Add your command handler code here } void CFREDDoc::OnEditHold() { // TODO: Add your command handler code here } void CFREDDoc::OnEditFetch() { // TODO: Add your command handler code here } void CFREDDoc::OnEditUndo() { // TODO: Add your command handler code here } void CFREDDoc::OnFilePreferences() { CPrefsDlg dlg; // Initialize dialog data dlg.m_ConfirmDeleting = confirm_deleting; dlg.m_ShowCapitalShips = show_capital_ships; dlg.m_ShowElevations = show_elevations; dlg.m_ShowFighters = show_fighters; dlg.m_ShowGrid = show_grid; dlg.m_ShowMiscObjects = show_misc_objects; dlg.m_ShowPlanets = show_planets; dlg.m_ShowWaypoints = show_waypoints; dlg.m_ShowStarfield = show_starfield; // Invoke the dialog box if (dlg.DoModal() == IDOK) { // retrieve the dialog data confirm_deleting = dlg.m_ConfirmDeleting; show_capital_ships = dlg.m_ShowCapitalShips; show_elevations = dlg.m_ShowElevations; show_fighters = dlg.m_ShowFighters; show_grid = dlg.m_ShowGrid; show_misc_objects = dlg.m_ShowMiscObjects; show_planets = dlg.m_ShowPlanets; show_waypoints = dlg.m_ShowWaypoints; show_starfield = dlg.m_ShowStarfield; } } // initialize (clear out) the mission, so it's empty and ready to use. void CFREDDoc::editor_init_mission() { reset_mission(); SetModifiedFlag(FALSE); } /* void CFREDDoc::OnFileNew() { // If mission has been modified, offer to save before continuing. while (IsModified()) { int rval; rval = MessageBox(NULL, "You have not saved your work.\n(Which isn't surprising...)\nSave it now?", "Creating New Mission", MB_YESNOCANCEL + MB_ICONEXCLAMATION); if (rval == IDYES) { OnFileSave(); } else if (rval == IDCANCEL) return; else if (rval == IDNO) break; } editor_init_mission(); } */ void CFREDDoc::UpdateStatus(int flags) { if (FREDDoc_ptr) if (flags & US_WORLD_CHANGED) FREDDoc_ptr->SetModifiedFlag(); } void CFREDDoc::OnEditClearAll() { DeleteContents(); } void CFREDDoc::DeleteContents() { editor_init_mission(); } void set_modified(BOOL arg) { Local_modified = arg; FREDDoc_ptr->SetModifiedFlag(arg); } // call this if an unknown ship class was discovered during parsing. Sets up a warning message for players void fred_notify_unknown_ship_during_parse() { Fred_found_unknown_ship_during_parsing = 1; } ////////////////////////////////////////////////////////////////////////// // // Below is old, obsolete code, kept around just in case it might be found // useful some time in the future for something. // ////////////////////////////////////////////////////////////////////////// #if 0 #define SerializeFloat(fp, mode, f) if (mode == 1) fp->Write(&f, sizeof(float)); else fp->Read(&f, sizeof(float)) #define SerializeInt(fp, mode, f) if (mode == 1) fp->Write(&f, sizeof(int)); else fp->Read(&f, sizeof(int)) void SerializeVector(XFILE *fp, int mode, vector *v) { SerializeFloat(fp, mode, v->x); SerializeFloat(fp, mode, v->y); SerializeFloat(fp, mode, v->z); } void SerializeMatrix(XFILE *fp, int mode, matrix *m) { SerializeVector(fp, mode, &m->rvec); SerializeVector(fp, mode, &m->uvec); SerializeVector(fp, mode, &m->fvec); } void SerializePhysicsInfo(XFILE *fp, int mode, physics_info *pi) { SerializeFloat(fp, mode, pi->mass); SerializeFloat(fp, mode, pi->drag); SerializeVector(fp, mode, &pi->max_thrust); SerializeVector(fp, mode, &pi->max_rotthrust); SerializeFloat(fp, mode, pi->turnroll); SerializeInt(fp, mode, pi->flags); SerializeVector(fp, mode, &pi->velocity); SerializeVector(fp, mode, &pi->rotvel); SerializeVector(fp, mode, &pi->thrust); SerializeVector(fp, mode, &pi->rotthrust); } ///////////////////////////////////////////////////////////////////////////// // CFREDDoc serialization void SerializeObject(XFILE *fp, int mode, object *objp) { SerializeInt(fp, mode, objp->signature); SerializeInt(fp, mode, objp->type); SerializeInt(fp, mode, objp->parent); SerializeInt(fp, mode, objp->parent_sig); SerializeInt(fp, mode, objp->parent_type); SerializeInt(fp, mode, objp->instance); SerializeInt(fp, mode, objp->flags); SerializeInt(fp, mode, objp->flags2); // Goober5000 - code is obsolete, but I added this just in case SerializeFloat(fp, mode, objp->radius); // SerializeInt(fp, mode, objp->wing); SerializePhysicsInfo(fp, mode, &objp->phys_info); SerializeVector(fp, mode, &objp->pos); SerializeMatrix(fp, mode, &objp->orient); } void SerializeAI(XFILE *fp, int mode, ai_info *aip) { SerializeInt(fp, mode, aip->shipnum); SerializeInt(fp, mode, aip->type); SerializeInt(fp, mode, aip->wing); //MWA -- SerializeInt(fp, mode, aip->current_waypoint); } void SerializeShip(XFILE *fp, int mode, ship *shipp) { SerializeInt(fp, mode, shipp->objnum); SerializeInt(fp, mode, shipp->ai_index); SerializeInt(fp, mode, shipp->subtype); SerializeInt(fp, mode, shipp->modelnum); SerializeInt(fp, mode, shipp->hits); SerializeInt(fp, mode, shipp->dying); } void SerializeGrid(XFILE *fp, int mode, grid *gridp) { int i; SerializeInt(fp, mode, gridp->nrows); SerializeInt(fp, mode, gridp->ncols); SerializeMatrix(fp, mode, &gridp->gmatrix); SerializePhysicsInfo(fp, mode, &gridp->physics); SerializeFloat(fp, mode, gridp->square_size); SerializeFloat(fp, mode, gridp->planeD); for (i=0; igpoints[i]); } void cfile_serialize(XFILE *fp, int flag) { int i; int highest_object_index = 0, highest_ship_index = 0, highest_ai_index = 0; Assert((flag == 0) || (flag == 1)); // fp = cfopen(filename, flag ? "wb" : "rb"); // if (!fp) // MessageBox(NULL, strerror(errno), "File Open Error!", MB_ICONSTOP); // Find highest used object if writing. if (flag == 1) { for (i=MAX_OBJECTS-1; i>0; i--) if (Objects[i].type != OBJ_NONE) { highest_object_index = i; break; } } if (flag == 0) { num_ships = 0; num_objects = 0; } SerializeInt(fp, flag, highest_object_index); for (i=1; i<=highest_object_index; i++) { SerializeObject(fp, flag, &Objects[i]); if (flag == 0) if (Objects[i].type != OBJ_NONE) num_objects++; } // Read/write ships if (flag == 1) { for (i=MAX_SHIPS-1; i>0; i--) if (Ships[i].objnum) { highest_ship_index = i; break; } } SerializeInt(fp, flag, highest_ship_index); for (i=1; i<=highest_ship_index; i++) { SerializeShip(fp, flag, &Ships[i]); if (flag == 0) if (Ships[i].objnum) num_ships++; } // Read/write AI info if (flag == 1) { for (i=MAX_AI_INFO-1; i>0; i--) if (Ai_info[i].shipnum) { highest_ai_index = i; break; } } SerializeInt(fp, flag, highest_ai_index); for (i=1; i<=highest_ai_index; i++) SerializeAI(fp, flag, &Ai_info[i]); } void cfile_serialize_editor(XFILE *fp, int flag) { // Editor only stuff SerializeMatrix(fp, flag, &view_orient); SerializeVector(fp, flag, &view_pos); SerializeInt(fp, flag, Control_mode); SerializeInt(fp, flag, cur_object_index); SerializeInt(fp, flag, cur_wing); SerializeGrid(fp, flag, The_grid); } #endif // Goober5000 void CFREDDoc::OnFileImportFSM() { char fs1_mission_path[MAX_PATH_LEN]; char fs2_mission_path[MAX_PATH_LEN]; // path stuff { char *ch; // get base paths strcpy(fs1_mission_path, Fred_exe_dir); ch = strrchr(fs1_mission_path, DIR_SEPARATOR_CHAR); if (ch != NULL) *ch = '\0'; strcpy(fs2_mission_path, Fred_exe_dir); ch = strrchr(fs2_mission_path, DIR_SEPARATOR_CHAR); if (ch != NULL) *ch = '\0'; // estimate the mission path for FS1 if ((ch = stristr(fs1_mission_path, "FreeSpace2")) >= 0) { strcpy(ch, "FreeSpace\\Data\\Missions"); } // estimate the mission path for FS2 strcat(fs2_mission_path, "\\Data\\Missions"); } // if mission has been modified, offer to save before continuing. if (!SaveModified()) return; // get location to import from CFileDialog dlgFile(TRUE, "fsm", NULL, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR | OFN_ALLOWMULTISELECT, "FreeSpace Missions (*.fsm)|*.fsm|All files (*.*)|*.*||"); dlgFile.m_ofn.lpstrTitle = "Select one or more missions to import"; dlgFile.m_ofn.lpstrInitialDir = fs1_mission_path; // get FSM files if (dlgFile.DoModal() != IDOK) return; // get location to save to CFolderDialog dlgFolder(_T("Select a location to save in"), fs2_mission_path, NULL); if(dlgFolder.DoModal() != IDOK) return; // clean things up first if (Briefing_dialog) Briefing_dialog->icon_select(-1); clear_mission(); // process all missions POSITION pos(dlgFile.GetStartPosition()); while(pos) { char *ch; char filename[1024]; char fs1_path[MAX_PATH_LEN]; char dest_path[MAX_PATH_LEN]; CString fs1_path_mfc(dlgFile.GetNextPathName(pos)); CFred_mission_save save; DWORD attrib; FILE *fp; // path name too long? if (strlen(fs1_path_mfc) > MAX_PATH_LEN - 1) continue; // nothing here? if (!strlen(fs1_path_mfc)) continue; // get our mission strcpy(fs1_path, fs1_path_mfc); // load mission into memory if (load_mission(fs1_path, MPF_IMPORT_FSM)) continue; // get filename ch = strrchr(fs1_path, DIR_SEPARATOR_CHAR) + 1; if (ch != NULL) strcpy(filename, ch); else strcpy(filename, fs1_path); // truncate extension ch = strrchr(filename, '.'); if (ch != NULL) *ch = '\0'; // add new extension strcat(filename, ".fs2"); strcpy(Mission_filename, filename); // get new path strcpy(dest_path, dlgFolder.GetFolderPath()); strcat(dest_path, "\\"); strcat(dest_path, filename); // check attributes fp = fopen(dest_path, "r"); if (fp) { fclose(fp); attrib = GetFileAttributes(dest_path); if (attrib & FILE_ATTRIBUTE_READONLY) continue; } // try to save it if (save.save_mission_file(dest_path)) continue; // success } create_new_mission(); MessageBox(NULL, "Import complete. Please check the destination folder to verify all missions were imported successfully.", "Status", MB_OK); } void restore_default_weapons(char *ships_tbl); void CFREDDoc::OnFileImportWeapons() { CString ships_tbl_mfc; char ships_tbl[MAX_PATH_LEN]; char *ships_tbl_text; char *ships_tbl_text_raw; char *ch; char temp[MAX_PATH_LEN]; // set up import dialog CFileDialog dlg(TRUE, "tbl", NULL, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR, "FreeSpace Tables (*.tbl)|*.tbl|All files (*.*)|*.*||"); dlg.m_ofn.lpstrTitle = "Specify the ships.tbl with the required loadouts"; // set initial path strcpy(temp, Fred_exe_dir); if ((ch = stristr(temp, "FreeSpace2")) >= 0) { strcpy(ch, "FreeSpace\\Data\\Tables"); dlg.m_ofn.lpstrInitialDir = temp; } // get ships.tbl if (dlg.DoModal() != IDOK) return; ships_tbl_mfc = dlg.GetPathName(); if (strlen(ships_tbl_mfc) > MAX_PATH_LEN - 1) { MessageBox(NULL, "Path name is too long", "Error", MB_OK); return; } if (!strlen(ships_tbl_mfc)) { return; } strcpy(ships_tbl, ships_tbl_mfc); // allocate junk ships_tbl_text = (char *) malloc(sizeof(char) * MISSION_TEXT_SIZE); ships_tbl_text_raw = (char *) malloc(sizeof(char) * MISSION_TEXT_SIZE); if (!ships_tbl_text || !ships_tbl_text_raw) { free(ships_tbl_text); free(ships_tbl_text_raw); Error(LOCATION, "Not enough memory to import weapons."); return; } // load the other table and convert, freeing memory after use read_file_text(ships_tbl, CF_TYPE_ANY, ships_tbl_text, ships_tbl_text_raw); free(ships_tbl_text_raw); restore_default_weapons(ships_tbl_text); free(ships_tbl_text); // we haven't saved it yet set_modified(TRUE); // error check and notify if (!Fred_view_wnd->global_error_check()) { Fred_view_wnd->MessageBox("Weapon loadouts successfully imported with no errors.", "Woohoo!"); } }