]> icculus.org git repositories - taylor/freespace2.git/blob - src/fred2/freddoc.cpp
fix issue with looping audio streams
[taylor/freespace2.git] / src / fred2 / freddoc.cpp
1 /*
2  * Copyright (C) Volition, Inc. 1999.  All rights reserved.
3  *
4  * All source code herein is the property of Volition, Inc. You may not sell 
5  * or otherwise commercially exploit the source or things you created based on
6  * the source.
7  */
8
9 /*
10  * $Logfile: /Freespace2/code/Fred2/FREDDoc.cpp $
11  * $Revision$
12  * $Date$
13  * $Author$
14  *
15  * FREDDoc.cpp : implementation of the CFREDDoc class
16  * Document class for document/view architechure, which we don't really use in
17  * Fred, but MFC forces you do use like it or not.  Handles loading/saving
18  * mainly.  Most of the MFC related stuff is handled in FredView.
19  *
20  * $Log$
21  * Revision 1.3  2002/06/09 04:41:16  relnev
22  * added copyright header
23  *
24  * Revision 1.2  2002/05/07 03:16:44  theoddone33
25  * The Great Newline Fix
26  *
27  * Revision 1.1.1.1  2002/05/03 03:28:08  root
28  * Initial import.
29  *
30  * 
31  * 7     7/23/99 2:12p Jamesa
32  * fix gamepalette request
33  * 
34  * 6     5/20/99 6:59p Dave
35  * Added alternate type names for ships. Changed swarm missile table
36  * entries.
37  * 
38  * 5     10/29/98 6:49p Dave
39  * Finished up Fred support for externalizing mission and campaign files.
40  * 
41  * 4     10/29/98 12:50p Dave
42  * Intermediate checkin for fred hash table stuff.
43  * 
44  * 3     10/28/98 11:30a Dave
45  * Temporary checkin.
46  * 
47  * 2     10/07/98 6:28p Dave
48  * Initial checkin. Renamed all relevant stuff to be Fred2 instead of
49  * Fred. Globalized mission and campaign file extensions. Removed Silent
50  * Threat specific code.
51  * 
52  * 1     10/07/98 3:00p Dave
53  * 
54  * 94    9/21/98 8:46p Dave
55  * Put in special check in fred for identifying unknown ships.
56  * 
57  * 93    9/16/98 6:54p Dave
58  * Upped  max sexpression nodes to 1800 (from 1600). Changed FRED to sort
59  * the ship list box. Added code so that tracker stats are not stored with
60  * only 1 player.
61  * 
62  * 92    8/13/98 9:53a Hoffoss
63  * Fixed bug where loading mission doesn't update palette used for that
64  * mission.
65  * 
66  * 91    4/30/98 8:23p John
67  * Fixed some bugs with Fred caused by my new cfile code.
68  * 
69  * 90    4/28/98 2:13p Hoffoss
70  * Added code to help keep invalid player ship types from existing in
71  * mission.
72  * 
73  * 89    4/10/98 10:22p Mike
74  * Fix bug in parsing medals.tbl.
75  * 
76  * 88    4/10/98 4:51p Hoffoss
77  * Made several changes related to tooltips.
78  * 
79  * 87    3/25/98 4:14p Hoffoss
80  * Split ship editor up into ship editor and a misc dialog, which tracks
81  * flags and such.
82  * 
83  * 86    3/10/98 4:26p Hoffoss
84  * Changed jump node structure to include a name.  Position is now taken
85  * from the object (each jump node has an associated object now).
86  * 
87  * 85    2/26/98 4:59p Allender
88  * groundwork for team vs team briefings.  Moved weaponry pool into the
89  * Team_data structure.  Added team field into the p_info structure.
90  * Allow for mutliple structures in the briefing code.
91  * 
92  * 84    1/28/98 11:00a Johnson
93  * Fixed parse code for medals table (new field)
94  * 
95  * 83    11/06/97 4:37p Allender
96  * a ton of medal work.  Removed an uneeded element in the scoring
97  * structure.  Fix up medals screen to apprioriate display medals (after
98  * mask was changed). Fix Fred to only display medals which may actually
99  * be granted.  Added image_filename to player struct for Jason Hoffoss
100  * 
101  * 82    11/05/97 10:19p Mike
102  * Comment out call to parse_medal_tbl() to allow Fred to run.
103  * 
104  * 81    11/05/97 4:43p Allender
105  * reworked medal/rank system to read all data from tables.  Made Fred
106  * read medals.tbl.  Changed ai-warp to ai-warp-out which doesn't require
107  * waypoint for activation
108  * 
109  * 80    11/04/97 4:50p Hoffoss
110  * Made mission loading failure display an error message stating so.
111  * 
112  * 79    11/04/97 4:33p Hoffoss
113  * Made saving keep the current briefing state intact.
114  * 
115  * 78    10/20/97 1:20p Hoffoss
116  * Fixed bug loading mission file after a save.
117  * 
118  * 77    10/19/97 11:36p Hoffoss
119  * Made mission saving call reload the mission after saving it to verify
120  * it was written error free.
121  * 
122  * 76    10/08/97 11:47a Hoffoss
123  * Added better fred handling of Weaponry_pool.
124  * 
125  * 75    9/20/97 8:16a John
126  * Made .clr files go into the Cache directory. Replaced cfopen(name,NULL)
127  * to delete a file with cf_delete.
128  * 
129  * 74    9/18/97 11:52a Johnson
130  * Fixed bug with player starts count being incorrect.
131  * 
132  * 73    9/17/97 11:58a Hoffoss
133  * Fixed mission load code to properly set arrival cues to player ships.
134  * 
135  * 72    9/17/97 10:32a Allender
136  * fixup references to old "Player" ship to new real shipname
137  * 
138  * 71    9/16/97 9:41p Hoffoss
139  * Changed Fred code around to stop using Parse_player structure for
140  * player information, and use actual ships instead.
141  * 
142  * 70    9/09/97 6:50p Hoffoss
143  * Fixed bug with mission saving.
144  * 
145  * 69    9/09/97 1:55p Hoffoss
146  * Fixed bug with saving missions that are readonly.
147  * 
148  * 68    8/21/97 1:49p Hoffoss
149  * Fixed bugs with loading files.  Wasn't clearing the last mission first,
150  * and multiplayer starts in a mission caused it to think it was modified
151  * right away.
152  * 
153  * 67    8/20/97 5:45p Hoffoss
154  * Fixed bugs with mission name in sexp in non campaign mode in Fred.
155  * 
156  * 66    8/20/97 4:03p Hoffoss
157  * Fixed bug in reload current mission (revert).
158  * 
159  * 65    8/17/97 10:22p Hoffoss
160  * Fixed several bugs in Fred with Undo feature.  In the process, recoded
161  * a lot of CFile.cpp.
162  * 
163  * 64    8/16/97 9:24p Hoffoss
164  * Added support for team of players in multiplayer.
165  * 
166  * 63    8/16/97 6:44p Hoffoss
167  * Changes to allow any player to be in a wing.
168  * 
169  * 62    8/16/97 3:53p Hoffoss
170  * Added OF_NO_SHIELDS define and support in Fred and mission load/save.
171  * 
172  * 61    8/13/97 5:49p Hoffoss
173  * Fixed bugs, made additions.
174  * 
175  * 60    8/13/97 12:46p Hoffoss
176  * Added campaign error checker, accelerator table, and mission goal data
177  * listings to sexp tree right click menu.
178  * 
179  * 59    8/12/97 1:55a Hoffoss
180  * Made extensive changes to object reference checking and handling for
181  * object deletion call.
182  * 
183  * 58    7/31/97 5:55p John
184  * made so you pass flags to obj_create.
185  * Added new collision code that ignores any pairs that will never
186  * collide.
187  * 
188  * 57    7/30/97 2:10p Hoffoss
189  * Made new missions that have never been saved yet save backups.
190  * 
191  * 56    7/28/97 3:50p Hoffoss
192  * Added global error checker call to mission load and save.
193  * 
194  * 55    7/10/97 2:32p Hoffoss
195  * Made message editor dialog box modeless.
196  * 
197  * 54    7/08/97 11:35a Hoffoss
198  * Fixed bug in initial orders, and also redid how shields are handled by
199  * Fred.
200  * 
201  * 53    6/26/97 5:18p Hoffoss
202  * Major rework of briefing editor functionality.
203  * 
204  * 52    6/24/97 10:22a Hoffoss
205  * Added a forced update for briefing info prior to a mission save.
206  * 
207  * 51    6/19/97 11:34a Hoffoss
208  * Fixed bug in auto mission convertion.
209  * 
210  * 50    6/18/97 3:25p Hoffoss
211  * Added autoconverting of old ship names (for ships in wings) at mission
212  * load time, and added an hourglass cursor change when autosaving.
213  * 
214  * 49    6/17/97 11:07a Hoffoss
215  * Fixed a few bugs: revert doesn't reset mission first, and sexp tree
216  * copy doesn't act act as a single chain.
217  * 
218  * 48    6/11/97 10:02a Comet
219  * fixed a bug.
220  * 
221  * 47    6/09/97 4:57p Hoffoss
222  * Added autosave and undo to Fred.
223  * 
224  * 46    6/05/97 6:10p Hoffoss
225  * Added features: Autosaving, object hiding.  Also fixed some minor bugs.
226  * 
227  * 45    5/23/97 3:18p Hoffoss
228  * Event editor made modeless.
229  * 
230  * 44    5/21/97 5:42p Hoffoss
231  * Added features requested on Todo list.
232  * 
233  * 43    5/01/97 4:14p Hoffoss
234  * Viewer position saved to missions now for Fred restoration of state.
235  * 
236  * 42    4/25/97 3:53p Hoffoss
237  * Fixed bug in weapons save/load and moved weapon look up function to
238  * weapons.cpp.
239  * 
240  * 41    4/25/97 3:28p Mike
241  * Making shield multi-part.
242  * 
243  * 40    4/21/97 5:02p Hoffoss
244  * Player/player status editing supported, and both saved and loaded from
245  * Mission files.
246  * 
247  * 39    3/20/97 3:55p Hoffoss
248  * Major changes to how dialog boxes initialize (load) and update (save)
249  * their internal data.  This should simplify things and create less
250  * problems.
251  * 
252  * 38    3/04/97 6:27p Hoffoss
253  * Changes to Fred to handle new wing structure.
254  * 
255  * 37    2/28/97 11:31a Hoffoss
256  * Implemented modeless dialog saving and restoring, and changed some
257  * variables names.
258  * 
259  * 36    2/27/97 3:09p Allender
260  * major wing structure enhancement.  simplified wing code.  All around
261  * better wing support
262  * 
263  * 35    2/20/97 4:03p Hoffoss
264  * Several ToDo items: new reinforcement clears arrival cue, reinforcement
265  * control from ship and wing dialogs, show grid toggle.
266  * 
267  * 34    2/17/97 5:28p Hoffoss
268  * Checked RCS headers, added them were missing, changing description to
269  * something better, etc where needed.
270  * 
271  * 14    2/12/97 12:25p Hoffoss
272  * Expanded on global error checker, added initial orders conflict
273  * checking and warning, added waypoint editor dialog and code.
274  * 
275  * 13    1/30/97 2:24p Hoffoss
276  * Added remaining mission file structures and implemented load/save of
277  * them.
278  *
279  * $NoKeywords: $
280  */
281
282 #include "stdafx.h"
283 #include "fred.h"
284 #include <stdlib.h>
285
286 #include "freddoc.h"
287 #include "fredview.h"
288 #include "prefsdlg.h"
289
290 #include "3d.h"
291 #include "object.h"
292 #include "editor.h"
293 #include "ai.h"
294 #include "ailocal.h"
295 #include "cfile.h"
296 #include "ship.h"
297 #include "missionparse.h"
298 #include "missiongoals.h"
299 #include "missionsave.h"
300 #include "weapon.h"
301 #include "management.h"
302 #include "linklist.h"
303 #include "fredrender.h"
304 #include "mainfrm.h"
305 #include "eventeditor.h"
306 #include "aigoals.h"
307 #include "messageeditordlg.h"
308 #include "palman.h"
309 #include "fhash.h"
310
311 extern int num_objects;
312
313 #ifdef _DEBUG
314 #define new DEBUG_NEW
315 #undef THIS_FILE
316 static char THIS_FILE[] = __FILE__;
317 #endif
318
319 //      In editor mode, use class CFile, in game, use CFILE (our file)
320 #define XFILE CFile
321
322 /////////////////////////////////////////////////////////////////////////////
323 // CFREDDoc
324
325 IMPLEMENT_DYNCREATE(CFREDDoc, CDocument)
326
327 BEGIN_MESSAGE_MAP(CFREDDoc, CDocument)
328         //{{AFX_MSG_MAP(CFREDDoc)
329         ON_COMMAND(ID_EDIT_DELETE, OnEditDelete)
330         ON_COMMAND(ID_DUPLICATE, OnDuplicate)
331         ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
332         ON_COMMAND(ID_EDIT_CUT, OnEditCut)
333         ON_COMMAND(ID_EDIT_HOLD, OnEditHold)
334         ON_COMMAND(ID_EDIT_FETCH, OnEditFetch)
335         ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
336         ON_COMMAND(ID_EDIT_UNDO, OnEditUndo)
337         ON_COMMAND(ID_FILE_PREFERENCES, OnFilePreferences)
338         //}}AFX_MSG_MAP
339 END_MESSAGE_MAP()
340
341 /////////////////////////////////////////////////////////////////////////////
342 // CFREDDoc construction/destruction
343
344 //      Global pointer to the FREDDoc class.
345 //      Used by MK to, among other things, I hope, update the modified flag from
346 //      outside the FREDDoc class.
347 CFREDDoc *FREDDoc_ptr = NULL;
348 int Local_modified = 0;
349 int Undo_available = 0;
350 int Undo_count = 0;
351
352 extern int Fred_found_unknown_ship_during_parsing;
353
354 CFREDDoc::CFREDDoc()
355 {
356         int i;
357
358         FREDDoc_ptr = this;
359         confirm_deleting = TRUE;
360         show_capital_ships = TRUE;
361         show_elevations = TRUE;
362         show_fighters = TRUE;
363         show_grid = TRUE;
364         show_misc_objects = TRUE;
365         show_planets = TRUE;
366         show_waypoints = TRUE;
367         show_starfield = TRUE;
368
369         for (i=0; i<BACKUP_DEPTH; i++)
370                 undo_desc[i].Empty();
371 }
372
373 CFREDDoc::~CFREDDoc()
374 {
375 }
376
377 BOOL CFREDDoc::OnNewDocument()
378 {
379         if (!CDocument::OnNewDocument())
380                 return FALSE;
381
382         // TODO: add reinitialization code here
383         confirm_deleting = TRUE;
384         show_capital_ships = FALSE;
385         show_elevations = TRUE;
386         show_fighters = TRUE;
387         show_grid = FALSE;
388         show_misc_objects = TRUE;
389         show_planets = FALSE;
390         show_waypoints = TRUE;
391         show_starfield = FALSE;
392         // (SDI documents will reuse this document)
393
394         return TRUE;
395 }
396
397 // read in a new mission file from disk
398 BOOL CFREDDoc::OnOpenDocument(LPCTSTR pathname)
399 {
400         char name[1024];
401         int i, len;
402
403         if (pathname)
404                 strcpy(mission_pathname, pathname);
405
406         if (Briefing_dialog)
407                 Briefing_dialog->icon_select(-1);  // clean things up first
408
409         len = strlen(mission_pathname);
410         strcpy(name, mission_pathname);
411         if (name[len - 4] == '.')
412                 len -= 4;
413
414         name[len] = 0;  // drop extension
415         i = len;
416         while (i--)
417                 if ((name[i] == '\\') || (name[i] == ':'))
418                         break;
419
420         strcpy(Mission_filename, name + i + 1);
421 //      for (i=1; i<=BACKUP_DEPTH; i++) {
422 //              sprintf(name + len, ".%.3d", i);
423 //              unlink(name);
424 //      }
425
426         if (load_mission(mission_pathname)) {
427                 *Mission_filename = 0;
428                 return FALSE;
429         }
430
431         Fred_view_wnd->global_error_check();
432         autosave("nothing");
433         Undo_count = 0;
434         return TRUE;
435 }
436
437 // save mission to a file
438 BOOL CFREDDoc::OnSaveDocument(LPCTSTR pathname)
439 {
440         CFred_mission_save save;
441         char name[1024];
442         int len;
443         DWORD attrib;
444         FILE *fp;
445
446         len = strlen(pathname);
447         strcpy(name, pathname);
448         if (name[len - 4] == '.')
449                 len -= 4;
450
451         name[len] = 0;  // drop extension
452         while (len--)
453                 if ((name[len] == '\\') || (name[len] == ':'))
454                         break;
455
456         strcpy(Mission_filename, name + len + 1);
457         Fred_view_wnd->global_error_check();
458         if (Briefing_dialog) {
459                 Briefing_dialog->update_data(1);
460                 Briefing_dialog->save_editor_state();
461         }
462         
463         if (Event_editor_dlg)
464                 Fred_main_wnd->MessageBox("Event editor dialog is still open, so changes there won't be saved");
465
466         if (Message_editor_dlg)
467                 Fred_main_wnd->MessageBox("Message editor dialog is still open, so changes there won't be saved");
468
469         fp = fopen(pathname, "r");
470         if (fp) {
471                 fclose(fp);
472                 attrib = GetFileAttributes(pathname);
473                 if (attrib & FILE_ATTRIBUTE_READONLY) {
474                         Fred_main_wnd->MessageBox("File is read-only.  You need to check it out before saving to it");
475                         return FALSE;
476                 }
477         }       
478
479         if (save.save_mission_file((char *) pathname)) {
480                 Fred_main_wnd->MessageBox("An error occured while saving!", NULL, MB_OK | MB_ICONEXCLAMATION);
481                 return FALSE;
482         }
483
484         SetModifiedFlag(FALSE);
485         if (load_mission((char *) pathname))
486                 Error(LOCATION, "Failed attempting to reload mission after saving.  Report this bug now!");
487
488         if (Briefing_dialog) {
489                 Briefing_dialog->restore_editor_state();
490                 Briefing_dialog->update_data(1);
491         }
492
493         return TRUE;
494 //      return CDocument::OnSaveDocument(pathname);
495 }
496
497 int CFREDDoc::check_undo()
498 {
499         char name[256];
500         FILE *fp;
501
502         Undo_available = 0;
503         if (!Undo_count)
504                 return 0;
505
506         strcpy(name, MISSION_BACKUP_NAME);
507         strcat(name, ".002");
508         fp = fopen(name, "r");
509         if (!fp)
510                 return 0;
511
512         fclose(fp);
513         Undo_available = 1;
514         return 1;
515 }
516
517 int CFREDDoc::autosave(char *desc)
518 {
519         int i;
520         CFred_mission_save save;
521         CWaitCursor wait;
522
523         if (Autosave_disabled)
524                 return 0;
525
526         if (Briefing_dialog)
527                 Briefing_dialog->update_data(1);
528         
529         if (save.autosave_mission_file(MISSION_BACKUP_NAME)) {
530                 Undo_count = Undo_available = 0;
531                 return -1;
532         }
533
534         for (i=BACKUP_DEPTH; i>1; i--)
535                 undo_desc[i] = undo_desc[i - 1];
536
537         if (desc)
538                 undo_desc[1] = desc;
539         else
540                 undo_desc[1].Empty();
541
542         Undo_count++;
543         check_undo();
544         return 0;
545 }
546
547 int CFREDDoc::autoload()
548 {
549         char name[256], backup_name[256];
550         int i, r, len;
551         FILE *fp;
552
553         strcpy(name, MISSION_BACKUP_NAME);
554         strcat(name, ".002");
555         fp = fopen(name, "r");
556         if (!fp)
557                 return 0;
558
559         fclose(fp);
560         if (Briefing_dialog)
561                 Briefing_dialog->icon_select(-1);  // clean things up first
562
563 //      editor_init_mission();  
564         r = load_mission(name);
565         Update_window = 1;
566
567         strcpy(backup_name, MISSION_BACKUP_NAME);
568         len = strlen(backup_name);
569         strcat(backup_name, ".001");
570         cf_delete(backup_name, CF_TYPE_MISSIONS);
571
572         for (i=1; i<BACKUP_DEPTH; i++) {
573                 sprintf(backup_name + len, ".%.3d", i + 1);
574                 sprintf(name + len, ".%.3d", i);
575                 cf_rename(backup_name, name, CF_TYPE_MISSIONS);
576                 undo_desc[i] = undo_desc[i + 1];
577         }
578
579         Undo_count--;
580         check_undo();
581         return r;
582 }
583
584 // read in a new mission file from disk
585 int CFREDDoc::load_mission(char *pathname)
586 {
587         char name[512], *old_name;
588         int i, j, k, ob;
589         int used_pool[MAX_WEAPON_TYPES];
590         waypoint_list *wptr;
591         object *objp;
592
593         Parse_viewer_pos = view_pos;
594         Parse_viewer_orient = view_orient;
595
596         // activate the localizer hash table
597         fhash_flush();  
598
599         clear_mission();
600         Fred_found_unknown_ship_during_parsing = 0;
601         if (parse_main(pathname)) {
602                 sprintf(name, "Unable to load the file \"%s\"", pathname);
603                 Fred_view_wnd->MessageBox(name);
604                 create_new_mission();           
605                 return -1;
606         }
607
608         if(Fred_found_unknown_ship_during_parsing){
609                 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");
610         }
611         Fred_found_unknown_ship_during_parsing = 0;
612
613         for (i=0; i<Num_waypoint_lists; i++) {
614                 wptr = &Waypoint_lists[i];
615                 for (j=0; j<wptr->count; j++){
616                         ob = obj_create(OBJ_WAYPOINT, -1, i * 65536 + j, NULL, &wptr->waypoints[j], 0.0f, OF_RENDERS);
617                 }
618         }
619
620         obj_merge_created_list();
621         objp = GET_FIRST(&obj_used_list);
622         while (objp != END_OF_LIST(&obj_used_list)) {
623                 if (objp->flags & OF_PLAYER_SHIP) {
624                         SDL_assert(objp->type == OBJ_SHIP);
625                         objp->type = OBJ_START;
626 //                      Player_starts++;
627                 }
628
629                 objp = GET_NEXT(objp);
630         }
631
632         for (i=0; i<num_wings; i++) {
633                 for (j=0; j<Wings[i].wave_count; j++) {
634                         ob = Ships[Wings[i].ship_index[j]].objnum;
635                         wing_objects[i][j] = ob;
636                         Ships[Wings[i].ship_index[j]].wingnum = i;
637                         Ships[Wings[i].ship_index[j]].arrival_cue = Locked_sexp_false;
638                 }
639
640                 // fix old ship names for ships in wings if needed
641                 while (j--) {
642                         if ( (Objects[wing_objects[i][j]].type == OBJ_SHIP) || (Objects[wing_objects[i][j]].type == OBJ_START) ) {  // don't change player ship names
643                                 sprintf(name, "%s %d", Wings[i].name, j + 1);
644                                 old_name = Ships[Wings[i].ship_index[j]].ship_name;
645                                 if (stricmp(name, old_name)) {  // need to fix name
646                                         update_sexp_references(old_name, name);
647                                         ai_update_goal_references(REF_TYPE_SHIP, old_name, name);
648                                         for (k=0; k<Num_reinforcements; k++)
649                                                 if (!stricmp(old_name, Reinforcements[k].name)) {
650                                                         SDL_assert(strlen(name) < NAME_LENGTH);
651                                                         strcpy(Reinforcements[k].name, name);
652                                                 }
653
654                                         strcpy(Ships[Wings[i].ship_index[j]].ship_name, name);
655                                 }
656                         }
657                 }
658         }
659
660         generate_weaponry_usage_list(used_pool);
661         for ( j = 0; j < Num_teams; j++ ) {
662                 for (i=0; i<Num_weapon_types; i++) {
663                         Team_data[j].weaponry_pool[i] -= used_pool[i];  // convert weaponry_pool to be extras available beyond the current ships weapons
664                         if (Team_data[j].weaponry_pool[i] < 0)
665                                 Team_data[j].weaponry_pool[i] = 0;
666                 }
667         }
668
669         SDL_assert(Mission_palette >= 0);
670         SDL_assert(Mission_palette <= 98);
671
672         if (The_mission.flags & MISSION_FLAG_SUBSPACE) {
673                 strcpy(name, NOX("gamepalette-subspace"));
674         } else {
675                 strcpy(name, "gamepalette1-01");
676                 // sprintf(name, NOX("gamepalette1-%02d"), Mission_palette + 1);
677         }
678
679         palette_load_table(name);
680
681         // go through all ships and translate their alternate name indices      
682         objp = GET_FIRST(&obj_used_list);
683         while (objp != END_OF_LIST(&obj_used_list)) {
684                 // if this is a ship, check it, and mark its possible alternate name down in the auxiliary array
685                 if(((objp->type == OBJ_SHIP) || (objp->type == OBJ_START)) && (objp->instance >= 0) && (Ships[objp->instance].alt_type_index >= 0)){
686                         mission_parse_lookup_alt_index(Ships[objp->instance].alt_type_index, Fred_alt_names[objp->instance]);
687
688                         // also zero it
689                         Ships[objp->instance].alt_type_index = -1;
690                 }
691
692                 objp = GET_NEXT(objp);
693         }
694
695
696         view_pos = Parse_viewer_pos;
697         view_orient = Parse_viewer_orient;
698         set_modified(0);        
699
700         return 0;
701 }
702
703 //      Editor-level interface to mission load/save.
704
705 // Does nothing now.. Handled by OnOpenDocument and OnSaveDocument.  This is because we
706 // want to avoid using the CArchive for file I/O  -JH
707 void CFREDDoc::Serialize(CArchive& ar)
708 {
709         return;
710 /*  The original Serialize code
711         int             rw_flag;
712         XFILE           *fp;
713 //      CString CSfilename;
714 //      char            filename[128], *tfilename;
715
716         fp = ar.GetFile();
717         rw_flag = ar.IsStoring();
718
719 //      CSfilename = fp->GetFileName();
720 //      tfilename = CSfilename.GetBuffer(16);
721 //      strcpy(filename, tfilename);
722 //      CSfilename.ReleaseBuffer();
723 // -- Don't close this, it gets closed by MFC --        ar.Close();
724
725         cfile_serialize(fp, rw_flag);
726         cfile_serialize_editor(fp, rw_flag);
727 */
728 }
729
730 /////////////////////////////////////////////////////////////////////////////
731 // CFREDDoc diagnostics
732
733 #ifdef _DEBUG
734 void CFREDDoc::AssertValid() const
735 {
736         CDocument::AssertValid();
737 }
738
739 void CFREDDoc::Dump(CDumpContext& dc) const
740 {
741         CDocument::Dump(dc);
742 }
743 #endif //_DEBUG
744
745
746 /////////////////////////////////////////////////////////////////////////////
747 // CFREDDoc commands
748
749 void CFREDDoc::OnEditDelete() 
750 {
751         // TODO: Add your command handler code here
752         
753 }
754
755 void CFREDDoc::OnDuplicate() 
756 {
757         // TODO: Add your command handler code here
758         
759 }
760
761 void CFREDDoc::OnEditCopy() 
762 {
763         // TODO: Add your command handler code here
764         
765 }
766
767 void CFREDDoc::OnEditCut() 
768 {
769         // TODO: Add your command handler code here
770         
771 }
772
773 void CFREDDoc::OnEditPaste() 
774 {
775         // TODO: Add your command handler code here
776         
777 }
778
779 void CFREDDoc::OnEditHold() 
780 {
781         // TODO: Add your command handler code here
782         
783 }
784
785 void CFREDDoc::OnEditFetch() 
786 {
787         // TODO: Add your command handler code here
788         
789 }
790
791 void CFREDDoc::OnEditUndo() 
792 {
793         // TODO: Add your command handler code here
794         
795 }
796
797 void CFREDDoc::OnFilePreferences() 
798 {
799         CPrefsDlg dlg;
800         // Initialize dialog data
801         dlg.m_ConfirmDeleting = confirm_deleting;
802         dlg.m_ShowCapitalShips = show_capital_ships;
803         dlg.m_ShowElevations = show_elevations;
804         dlg.m_ShowFighters = show_fighters;
805         dlg.m_ShowGrid = show_grid;
806         dlg.m_ShowMiscObjects = show_misc_objects;
807         dlg.m_ShowPlanets = show_planets;
808         dlg.m_ShowWaypoints = show_waypoints;
809         dlg.m_ShowStarfield = show_starfield;
810
811         // Invoke the dialog box
812         if (dlg.DoModal() == IDOK)
813         {
814                 // retrieve the dialog data
815                 confirm_deleting = dlg.m_ConfirmDeleting;
816                 show_capital_ships = dlg.m_ShowCapitalShips;
817                 show_elevations = dlg.m_ShowElevations;
818                 show_fighters = dlg.m_ShowFighters;
819                 show_grid = dlg.m_ShowGrid;
820                 show_misc_objects = dlg.m_ShowMiscObjects;
821                 show_planets = dlg.m_ShowPlanets;
822                 show_waypoints = dlg.m_ShowWaypoints;
823                 show_starfield = dlg.m_ShowStarfield;
824         }
825
826 }
827
828 // initialize (clear out) the mission, so it's empty and ready to use.
829 void CFREDDoc::editor_init_mission()
830 {
831         reset_mission();
832         SetModifiedFlag(FALSE);
833 }
834 /*
835 void CFREDDoc::OnFileNew() 
836 {
837         // If mission has been modified, offer to save before continuing.
838         while (IsModified()) {
839                 int     rval;
840                 
841                 rval = MessageBox(NULL,
842                         "You have not saved your work.\n(Which isn't surprising...)\nSave it now?",
843                         "Creating New Mission",
844                         MB_YESNOCANCEL + MB_ICONEXCLAMATION);
845
846                 if (rval == IDYES) {
847                         OnFileSave();
848                 } else if (rval == IDCANCEL)
849                         return;
850                 else if (rval == IDNO)
851                         break;
852         }
853
854         editor_init_mission();
855
856 }
857 */
858 void CFREDDoc::UpdateStatus(int flags)
859 {
860         if (FREDDoc_ptr)
861                 if (flags & US_WORLD_CHANGED)
862                         FREDDoc_ptr->SetModifiedFlag();
863 }
864
865 void CFREDDoc::OnEditClearAll()
866 {
867    DeleteContents();
868 }
869   
870   
871 void CFREDDoc::DeleteContents()
872 {
873         editor_init_mission();
874 }
875
876 void set_modified(BOOL arg)
877 {
878         Local_modified = arg;
879         FREDDoc_ptr->SetModifiedFlag(arg);
880 }
881
882 // call this if an unknown ship class was discovered during parsing. Sets up a warning message for players
883 void fred_notify_unknown_ship_during_parse()
884 {
885         Fred_found_unknown_ship_during_parsing = 1;
886 }
887
888  //////////////////////////////////////////////////////////////////////////
889 //
890 // Below is old, obsolete code, kept around just in case it might be found
891 // useful some time in the future for something.
892 //
893  //////////////////////////////////////////////////////////////////////////
894
895 #if 0
896 #define SerializeFloat(fp, mode, f) if (mode == 1) fp->Write(&f, sizeof(float)); else fp->Read(&f, sizeof(float))
897 #define SerializeInt(fp, mode, f) if (mode == 1) fp->Write(&f, sizeof(int)); else fp->Read(&f, sizeof(int))
898
899 void SerializeVector(XFILE *fp, int mode, vector *v)
900 {
901         SerializeFloat(fp, mode, v->x);
902         SerializeFloat(fp, mode, v->y);
903         SerializeFloat(fp, mode, v->z);
904 }
905
906 void SerializeMatrix(XFILE *fp, int mode, matrix *m)
907 {
908         SerializeVector(fp, mode, &m->rvec);
909         SerializeVector(fp, mode, &m->uvec);
910         SerializeVector(fp, mode, &m->fvec);
911 }
912
913 void SerializePhysicsInfo(XFILE *fp, int mode, physics_info *pi)
914 {
915         SerializeFloat(fp, mode, pi->mass);
916         SerializeFloat(fp, mode, pi->drag);
917         SerializeVector(fp, mode, &pi->max_thrust);
918         SerializeVector(fp, mode, &pi->max_rotthrust);
919         SerializeFloat(fp, mode, pi->turnroll);
920         SerializeInt(fp, mode, pi->flags);
921         SerializeVector(fp, mode, &pi->velocity);
922         SerializeVector(fp, mode, &pi->rotvel);
923         SerializeVector(fp, mode, &pi->thrust);
924         SerializeVector(fp, mode, &pi->rotthrust);
925 }
926
927 /////////////////////////////////////////////////////////////////////////////
928 // CFREDDoc serialization
929 void SerializeObject(XFILE *fp, int mode, object *objp)
930 {
931         SerializeInt(fp, mode, objp->signature);
932         SerializeInt(fp, mode, objp->type);
933         SerializeInt(fp, mode, objp->parent);
934         SerializeInt(fp, mode, objp->parent_sig);
935         SerializeInt(fp, mode, objp->parent_type);
936         SerializeInt(fp, mode, objp->instance);
937         SerializeInt(fp, mode, objp->flags);
938         SerializeFloat(fp, mode, objp->radius);
939 //      SerializeInt(fp, mode, objp->wing);
940         SerializePhysicsInfo(fp, mode, &objp->phys_info);
941         SerializeVector(fp, mode, &objp->pos);
942         SerializeMatrix(fp, mode, &objp->orient);
943 }
944
945 void SerializeAI(XFILE *fp, int mode, ai_info *aip)
946 {
947         SerializeInt(fp, mode, aip->shipnum);
948         SerializeInt(fp, mode, aip->type);
949         SerializeInt(fp, mode, aip->wing);
950 //MWA --        SerializeInt(fp, mode, aip->current_waypoint);
951 }
952
953 void SerializeShip(XFILE *fp, int mode, ship *shipp)
954 {
955         SerializeInt(fp, mode, shipp->objnum);
956         SerializeInt(fp, mode, shipp->ai_index);
957         SerializeInt(fp, mode, shipp->subtype);
958         SerializeInt(fp, mode, shipp->modelnum);
959         SerializeInt(fp, mode, shipp->hits);
960         SerializeInt(fp, mode, shipp->dying);
961 }
962
963 void SerializeGrid(XFILE *fp, int mode, grid *gridp)
964 {
965         int     i;
966
967         SerializeInt(fp, mode, gridp->nrows);
968         SerializeInt(fp, mode, gridp->ncols);
969         SerializeMatrix(fp, mode, &gridp->gmatrix);
970         SerializePhysicsInfo(fp, mode, &gridp->physics);
971         SerializeFloat(fp, mode, gridp->square_size);
972         SerializeFloat(fp, mode, gridp->planeD);
973         
974         for (i=0; i<MAX_GRID_POINTS; i++)
975                 SerializeVector(fp, mode, &gridp->gpoints[i]);
976
977 }
978
979 void cfile_serialize(XFILE *fp, int flag)
980 {
981         int     i;
982         int     highest_object_index = 0, highest_ship_index = 0, highest_ai_index = 0;
983
984         SDL_assert((flag == 0) || (flag == 1));
985
986 //      fp = cfopen(filename, flag ? "wb" : "rb");
987 //      if (!fp)
988 //              MessageBox(NULL, strerror(errno), "File Open Error!", MB_ICONSTOP);
989
990         //      Find highest used object if writing.
991         if (flag == 1) {
992                 for (i=MAX_OBJECTS-1; i>0; i--)
993                         if (Objects[i].type != OBJ_NONE) {
994                                 highest_object_index = i;
995                                 break;
996                         }
997         }
998
999         if (flag == 0) {
1000                 num_ships = 0;
1001                 num_objects = 0;
1002         }
1003
1004         SerializeInt(fp, flag, highest_object_index);
1005
1006         for (i=1; i<=highest_object_index; i++) {
1007                 SerializeObject(fp, flag, &Objects[i]);
1008                 if (flag == 0)
1009                         if (Objects[i].type != OBJ_NONE)
1010                                 num_objects++;
1011         }
1012
1013         //      Read/write ships
1014         if (flag == 1) {
1015                 for (i=MAX_SHIPS-1; i>0; i--)
1016                         if (Ships[i].objnum) {
1017                                 highest_ship_index = i;
1018                                 break;
1019                         }
1020         }
1021
1022         SerializeInt(fp, flag, highest_ship_index);
1023
1024         for (i=1; i<=highest_ship_index; i++) {
1025                 SerializeShip(fp, flag, &Ships[i]);
1026                 if (flag == 0)
1027                         if (Ships[i].objnum)
1028                                 num_ships++;
1029         }
1030
1031         // Read/write AI info
1032         if (flag == 1) {
1033                 for (i=MAX_AI_INFO-1; i>0; i--)
1034                         if (Ai_info[i].shipnum) {
1035                                 highest_ai_index = i;
1036                                 break;
1037                         }
1038         }
1039
1040         SerializeInt(fp, flag, highest_ai_index);
1041         
1042         for (i=1; i<=highest_ai_index; i++)
1043                 SerializeAI(fp, flag, &Ai_info[i]);
1044 }
1045
1046 void cfile_serialize_editor(XFILE *fp, int flag)
1047 {
1048         //      Editor only stuff
1049         SerializeMatrix(fp, flag, &view_orient);
1050         SerializeVector(fp, flag, &view_pos);
1051         
1052         SerializeInt(fp, flag, Control_mode);
1053         SerializeInt(fp, flag, cur_object_index);
1054         SerializeInt(fp, flag, cur_wing);
1055
1056         SerializeGrid(fp, flag, The_grid);
1057
1058 }
1059 #endif
1060