]> icculus.org git repositories - taylor/freespace2.git/blob - src/fred2/fred.cpp
The Great Newline Fix
[taylor/freespace2.git] / src / fred2 / fred.cpp
1 /*
2  * $Logfile: /Freespace2/code/Fred2/FRED.cpp $
3  * $Revision$
4  * $Date$
5  * $Author$
6  *
7  * FRED.cpp : Defines the class behaviors for the application.
8  * Global editor dialog box classes are instantiated here, initializes the
9  * application (MFC level at least), processes the INI file.
10  *
11  * $Log$
12  * Revision 1.2  2002/05/07 03:16:44  theoddone33
13  * The Great Newline Fix
14  *
15  * Revision 1.1.1.1  2002/05/03 03:28:08  root
16  * Initial import.
17  *
18  * 
19  * 6     5/19/99 4:07p Dave
20  * Moved versioning code into a nice isolated common place. Fixed up
21  * updating code on the pxo screen. Fixed several stub problems.
22  * 
23  * 5     3/26/99 4:49p Dave
24  * Made cruisers able to dock with stuff. Made docking points and paths
25  * visible in fred.
26  * 
27  * 4     3/20/99 5:09p Dave
28  * Fixed release build fred warnings and unhandled exception.
29  * 
30  * 3     10/29/98 10:41a Dave
31  * Change the way cfile initializes exe directory.
32  * 
33  * 2     10/07/98 6:28p Dave
34  * Initial checkin. Renamed all relevant stuff to be Fred2 instead of
35  * Fred. Globalized mission and campaign file extensions. Removed Silent
36  * Threat specific code.
37  * 
38  * 1     10/07/98 3:01p Dave
39  * 
40  * 1     10/07/98 3:00p Dave
41  * 
42  * 71    7/02/98 12:17p Hoffoss
43  * Load and save options 'anti-aliased gridlines' and 'double fine
44  * gridlines'.
45  * 
46  * 70    5/22/98 11:02a Allender
47  * Added error conditions on compile and new MAX_SHIPS limits for when
48  * FRED is defined when building
49  * 
50  * 69    5/22/98 1:06a Hoffoss
51  * Made Fred not use OLE.
52  * 
53  * 68    4/17/98 1:41p Allender
54  * took out function calls in NDEBUG mode
55  * 
56  * 67    3/25/98 4:14p Hoffoss
57  * Split ship editor up into ship editor and a misc dialog, which tracks
58  * flags and such.
59  * 
60  * 66    3/23/98 4:04p Hoffoss
61  * Fixed dialog window initialization so it looks better at startup (they
62  * don't flash on for a second).
63  * 
64  * 65    3/19/98 11:41a Hoffoss
65  * Fixed problems with rendering and reading of flying controls in Fred.
66  * 
67  * 64    3/19/98 11:11a Allender
68  * made Fred actually be able to move camera again -- Hoffos is going to
69  * fix the code right.
70  * 
71  * 63    3/18/98 3:10p Allender
72  * fixed update problems in OnIdle routine
73  * 
74  * 62    2/06/98 4:39p Hoffoss
75  * Added better checking for whether Fred is in the foreground or
76  * background.
77  * 
78  * 61    8/19/97 5:46p Hoffoss
79  * Changed font used in Fred, and added display to show current eye
80  * position.
81  * 
82  * 60    8/17/97 10:22p Hoffoss
83  * Fixed several bugs in Fred with Undo feature.  In the process, recoded
84  * a lot of CFile.cpp.
85  * 
86  * 59    8/14/97 2:32p Hoffoss
87  * fixed bug where controlling an object doesn't cause screen updates, and
88  * added a number of cool features to viewpoint/control object code.
89  * 
90  * 58    8/13/97 1:38p Hoffoss
91  * Added ability to update multiple times, which in needed in one case to
92  * brute force redraw so deleted ships actually do get removed from the
93  * display.
94  * 
95  * 57    8/12/97 6:32p Hoffoss
96  * Added code to allow hiding of arrival and departure cues in editors.
97  * 
98  * 56    8/10/97 4:52p Hoffoss
99  * Made Fred startup with main window having focus.
100  * 
101  * 55    8/06/97 7:55p Hoffoss
102  * Fixed bug with objects not seeming to be where they are drawn (due to
103  * new briefing clip render stuff).  This caused rendering problems,
104  * though.  So I fixed those next.
105  * 
106  * 54    8/05/97 1:29p Hoffoss
107  * show sexp help saved between sessions.
108  * 
109  * 53    8/01/97 3:10p Hoffoss
110  * Made Sexp help hidable.
111  * 
112  * 52    8/01/97 12:49p Hoffoss
113  * Changed recently used files total to 9 instead of 4.
114  * 
115  * 51    6/18/97 11:46a Hoffoss
116  * Fixed initial order object reference updating and added briefing dialog
117  * window tracking data.
118  * 
119  * 50    6/03/97 10:18a Allender
120  * make showCmd default to maximized since 0 will make the window hidden
121  * by default
122  * 
123  * 49    6/02/97 5:18p Hoffoss
124  * Fixed bug in error checker and improved startup code.
125  * 
126  * 48    6/02/97 11:52a Hoffoss
127  * Custom cursors displayed when over objects in different modes.
128  * 
129  * 47    5/12/97 12:27p John
130  * Restructured Graphics Library to add support for multiple renderers.
131  * 
132  * 46    5/09/97 9:45a Hoffoss
133  * Added OLE initialization. (needed for drag and drop functionality)
134  * 
135  * 45    5/06/97 10:34a Hoffoss
136  * Fixed bug where dialog boxes that change size (in the code) still
137  * retain their old size from the INI stored values.  They are resized now
138  * automatically.
139  * 
140  * 44    5/05/97 9:41a Hoffoss
141  * Campaign editor begun.
142  * 
143  * 43    5/02/97 8:39a Allender
144  * turn of heap allocation debuging
145  * 
146  * 42    4/29/97 1:58p Hoffoss
147  * Added some debugging to Fred to try and track down sexp corruption
148  * causes.
149  * 
150  * 41    4/28/97 3:43p Hoffoss
151  * Show_waypoints defaults to on for Fred, and is saved as a preference
152  * now.
153  * 
154  * 40    4/17/97 2:01p Hoffoss
155  * All dialog box window states are saved between sessions now.
156  * 
157  * 39    4/03/97 11:35a Hoffoss
158  * Fixed bugs: viewpoint didn't reset, initial orders not updated when
159  * referenced ship is renamed or deleted.
160  * 
161  * 38    4/01/97 11:43p Mike
162  * Resolve link errors due to addition of SystemVars.cpp.
163  * 
164  * 37    3/26/97 12:44p Hoffoss
165  * Took out the debugging 3d compass on/off toggling I put in to test
166  * rerendering with.
167  * 
168  * 36    3/20/97 3:55p Hoffoss
169  * Major changes to how dialog boxes initialize (load) and update (save)
170  * their internal data.  This should simplify things and create less
171  * problems.
172  * 
173  * 35    3/13/97 12:08p Hoffoss
174  * Waypoint path editor finished (apparently I didn't get around to
175  * completing it before).
176  * 
177  * 34    3/12/97 12:39p Hoffoss
178  * Fixed bugs in wing object management functions, several small additions
179  * and rearrangements.
180  * 
181  * 33    3/06/97 3:35p Hoffoss
182  * Added Show_outline stuff, moved show options to the view menu, fixed a
183  * bug in message dialog editor.
184  * 
185  * 32    2/28/97 11:31a Hoffoss
186  * Implemented modeless dialog saving and restoring, and changed some
187  * variables names.
188  * 
189  * 31    2/27/97 5:54p Hoffoss
190  * Implemented support for saving and restoring window positions.
191  * 
192  * 30    2/25/97 6:10p Hoffoss
193  * Fixed bug with modeless dialog box errors on update.
194  * 
195  * 29    2/24/97 12:50p Hoffoss
196  * First attempt at non-continuous redrawing.
197  * 
198  * 28    2/17/97 5:28p Hoffoss
199  * Checked RCS headers, added them were missing, changing description to
200  * something better, etc where needed.
201  * 
202  * 27    2/12/97 12:25p Hoffoss
203  * Expanded on global error checker, added initial orders conflict
204  * checking and warning, added waypoint editor dialog and code.
205  * 
206  * 26    1/30/97 2:24p Hoffoss
207  * Added remaining mission file structures and implemented load/save of
208  * them.
209  *
210  * $NoKeywords: $
211  */
212
213 #include "stdafx.h"
214 #include "fred.h"
215
216 #include "mainfrm.h"
217 #include "freddoc.h"
218 #include "fredview.h"
219 #include "fredrender.h"
220 #include "management.h"
221
222 #include "2d.h"
223 #include "key.h"
224 #include "object.h"
225 #include "editor.h"
226 #include "campaigntreewnd.h"
227 #include "campaigntreeview.h"
228 #include "campaigneditordlg.h"
229
230 #ifdef NDEBUG
231 #ifndef FRED
232 #error macro FRED is not defined when trying to build release Fred.  Please define FRED macro in build settings in all Fred projects
233 #endif
234 #endif
235
236 #ifdef _DEBUG
237 #define new DEBUG_NEW
238 #undef THIS_FILE
239 static char THIS_FILE[] = __FILE__;
240 #endif
241
242 int     Fred_running = 1;
243 int     User_interface = HOFFOSS_INTERFACE;
244 int     FrameCount = 0;
245 int     Fred_active = 1;
246 int     Update_window = 1;
247 HCURSOR h_cursor_move, h_cursor_rotate;
248
249 CWnd *Prev_window;
250 CShipEditorDlg  Ship_editor_dialog;
251 wing_editor             Wing_editor_dialog;
252 waypoint_path_dlg       Waypoint_editor_dialog;
253 bg_bitmap_dlg   *Bg_bitmap_dialog = NULL;
254 briefing_editor_dlg     *Briefing_dialog = NULL;
255
256 window_data Main_wnd_data;
257 window_data Ship_wnd_data;
258 window_data Wing_wnd_data;
259 window_data Object_wnd_data;
260 window_data Mission_goals_wnd_data;
261 window_data Messages_wnd_data;
262 window_data Player_wnd_data;
263 window_data Events_wnd_data;
264 window_data Bg_wnd_data;
265 window_data Briefing_wnd_data;
266 window_data Reinforcement_wnd_data;
267 window_data Waypoint_wnd_data;
268 window_data Starfield_wnd_data;
269 window_data Asteroid_wnd_data;
270 window_data Mission_notes_wnd_data;
271
272 /////////////////////////////////////////////////////////////////////////////
273 // CFREDApp
274
275 BEGIN_MESSAGE_MAP(CFREDApp, CWinApp)
276         //{{AFX_MSG_MAP(CFREDApp)
277         ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
278                 // NOTE - the ClassWizard will add and remove mapping macros here.
279                 //    DO NOT EDIT what you see in these blocks of generated code!
280         //}}AFX_MSG_MAP
281         // Standard file based document commands
282         ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
283         ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
284         // Standard print setup command
285         ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)
286 END_MESSAGE_MAP()
287
288 /////////////////////////////////////////////////////////////////////////////
289 // CFREDApp construction
290
291 CFREDApp::CFREDApp()
292 {
293         app_init = 0;
294
295         #ifndef NDEBUG
296         outwnd_init();
297         #endif
298         // TODO: add construction code here,
299         // Place all significant initialization in InitInstance
300 }
301
302 /////////////////////////////////////////////////////////////////////////////
303 // The one and only CFREDApp object
304
305 CFREDApp theApp;
306
307 /////////////////////////////////////////////////////////////////////////////
308 // CFREDApp initialization
309 char *c;
310 char *tok = "whee";
311 BOOL CFREDApp::InitInstance()
312 {       
313         // disable the debug memory stuff
314         _CrtSetDbgFlag(~(_CRTDBG_ALLOC_MEM_DF) & _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG));
315
316         // Standard initialization
317         // If you are not using these features and wish to reduce the size
318         //  of your final executable, you should remove from the following
319         //  the specific initialization routines you do not need.
320
321 #ifdef _AFXDLL
322         Enable3dControls();                     // Call this when using MFC in a shared DLL
323 #else
324         Enable3dControlsStatic();       // Call this when linking to MFC statically
325 #endif
326
327         LoadStdProfileSettings(9);  // Load standard INI file options (including MRU)
328         User_interface = GetProfileInt("Preferences", "User interface", User_interface);
329         Show_stars = GetProfileInt("Preferences", "Show stars", Show_stars);
330         Show_grid_positions = GetProfileInt("Preferences", "Show grid positions", Show_grid_positions);
331         Show_coordinates = GetProfileInt("Preferences", "Show coordinates", Show_coordinates);
332         Show_compass = GetProfileInt("Preferences", "Show compass", Show_compass);
333         Show_ship_models = GetProfileInt("Preferences", "Show ship models", Show_ship_models);
334         Show_ship_info = GetProfileInt("Preferences", "Show ship info", Show_ship_info);
335         Show_outlines = GetProfileInt("Preferences", "Show outlines", Show_outlines);
336         Show_waypoints = GetProfileInt("Preferences", "Show waypoints", Show_waypoints);
337         Show_sexp_help = GetProfileInt("Preferences", "Show sexp help", Show_sexp_help);
338         physics_speed = GetProfileInt("Preferences", "Physics speed", physics_speed);
339         physics_rot = GetProfileInt("Preferences", "Physics rotation", physics_rot);
340         Hide_ship_cues = GetProfileInt("Preferences", "Hide ship cues", Hide_ship_cues);
341         Hide_wing_cues = GetProfileInt("Preferences", "Hide wing cues", Hide_wing_cues);
342         Autosave_disabled = GetProfileInt("Preferences", "Autosave disabled", Autosave_disabled);
343         double_fine_gridlines = GetProfileInt("Preferences", "Double fine gridlines", double_fine_gridlines);
344         Aa_gridlines = GetProfileInt("Preferences", "Anti aliased gridlines", Aa_gridlines);
345         Show_dock_points = GetProfileInt("Preferences", "Show dock points", Show_dock_points);
346         Show_paths_fred = GetProfileInt("Preferences", "Show paths", Show_paths_fred);
347         read_window("Main window", &Main_wnd_data);
348         read_window("Ship window", &Ship_wnd_data);
349         read_window("Wing window", &Wing_wnd_data);
350         read_window("Waypoint window", &Waypoint_wnd_data);
351         read_window("Object window", &Object_wnd_data);
352         read_window("Mission goals window", &Mission_goals_wnd_data);
353         read_window("Messages window", &Messages_wnd_data);
354         read_window("Player window", &Player_wnd_data);
355         read_window("Events window", &Events_wnd_data);
356         read_window("Bg window", &Bg_wnd_data);
357         read_window("Briefing window", &Briefing_wnd_data);
358         read_window("Reinforcement window", &Reinforcement_wnd_data);
359         read_window("Starfield window", &Starfield_wnd_data);
360         read_window("Asteroid window", &Asteroid_wnd_data);
361         read_window("Mission notes window", &Mission_notes_wnd_data);
362         write_ini_file(1);
363
364         // Register the application's document templates.  Document templates
365         //  serve as the connection between documents, frame windows and views.
366
367         CSingleDocTemplate* pDocTemplate;
368         pDocTemplate = new CSingleDocTemplate(
369                 IDR_MAINFRAME,
370                 RUNTIME_CLASS(CFREDDoc),
371                 RUNTIME_CLASS(CMainFrame),       // main SDI frame window
372                 RUNTIME_CLASS(CFREDView));
373         AddDocTemplate(pDocTemplate);
374
375         // Enable DDE Execute open
376         EnableShellOpen();
377         RegisterShellFileTypes(TRUE);   
378
379         // setup the fred exe directory so CFILE can init properly
380         /*
381         c = GetCommandLine();
382         Assert(c != NULL);
383         if(c == NULL){
384                 return FALSE;
385         } 
386         tok = strtok(c, " \n");
387         Assert(tok != NULL);
388         if(tok == NULL){
389                 return FALSE;           
390         }
391         // Fred_exe_dir = strdup(c);            
392         strcpy(Fred_exe_dir, tok);
393         */
394         strcpy(Fred_exe_dir, __argv[0]);
395
396         // Parse command line for standard shell commands, DDE, file open
397         CCommandLineInfo cmdInfo;
398         ParseCommandLine(cmdInfo);      
399
400         m_nCmdShow = Main_wnd_data.p.showCmd;
401         OnFileNew();
402
403         // Enable drag/drop open
404         m_pMainWnd->DragAcceptFiles();
405
406         h_cursor_move = LoadCursor(IDC_CURSOR1);
407         h_cursor_rotate = LoadCursor(IDC_CURSOR2);
408         return TRUE;
409 }
410
411 /////////////////////////////////////////////////////////////////////////////
412 // CAboutDlg dialog used for App About
413
414 class CAboutDlg : public CDialog
415 {
416 public:
417         CAboutDlg();
418
419 // Dialog Data
420         //{{AFX_DATA(CAboutDlg)
421         enum { IDD = IDD_ABOUTBOX };
422         //}}AFX_DATA
423
424         // ClassWizard generated virtual function overrides
425         //{{AFX_VIRTUAL(CAboutDlg)
426         protected:
427         virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
428         //}}AFX_VIRTUAL
429
430 // Implementation
431 protected:
432         //{{AFX_MSG(CAboutDlg)
433         //}}AFX_MSG
434         DECLARE_MESSAGE_MAP()
435 };
436
437 CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
438 {
439         //{{AFX_DATA_INIT(CAboutDlg)
440         //}}AFX_DATA_INIT
441 }
442
443 void CAboutDlg::DoDataExchange(CDataExchange* pDX)
444 {
445         CDialog::DoDataExchange(pDX);
446         //{{AFX_DATA_MAP(CAboutDlg)
447         //}}AFX_DATA_MAP
448 }
449
450 BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
451         //{{AFX_MSG_MAP(CAboutDlg)
452         //}}AFX_MSG_MAP
453 END_MESSAGE_MAP()
454
455 // App command to run the dialog
456 void CFREDApp::OnAppAbout()
457 {
458         CAboutDlg aboutDlg;
459         aboutDlg.DoModal();
460 }
461
462 /////////////////////////////////////////////////////////////////////////////
463 // CFREDApp commands
464
465 char *edit_mode_text[] = {
466         "Ships",
467         "Waypoints",
468 };
469 /*      "Grid",
470         "Wing",
471         "Object Relative"
472 };
473 */
474
475 char *control_mode_text[] = {
476         "Camera",
477         "Object"
478 };
479
480 void show_control_mode(void)
481 {
482         CString str;
483
484         CMainFrame* pFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd;
485         CStatusBar* pStatus = &pFrame->m_wndStatusBar;
486         //CStatusBarCtrl pStatusBarCtrl;
487
488         if (pStatus) {
489 //              pStatus->GetStatusBarCtrl().SetParts(NUM_STATUS_PARTS, parts);
490
491                 if (Marked)
492                         str.Format("Marked: %d", Marked);
493                 else
494                         str = _T("");
495                 pStatus->SetPaneText(1, str);
496
497                 if (viewpoint)
498                         str.Format("Viewpoint: %s", object_name(view_obj));
499                 else
500                         str.Format("Viewpoint: Camera");
501
502                 pStatus->SetPaneText(2, str);
503                 
504                 if (FREDDoc_ptr->IsModified())
505                         pStatus->SetPaneText(3, "MODIFIED");
506                 else
507                         pStatus->SetPaneText(3, "");
508
509                 str.Format("Units = %.1f Meters", The_grid->square_size);
510                 pStatus->SetPaneText(4, str);
511
512 //              pStatus->SetPaneText(4, "abcdefg");
513 //              pStatus->SetPaneText(4, "1234567890!");
514         }
515         
516 }
517
518 #define MAX_PENDING_MESSAGES    16
519
520 typedef struct {
521         int     frame_to_process, hwnd, id, wparam, lparam;
522 } pending_message;
523
524 pending_message Pending_messages[MAX_PENDING_MESSAGES];
525
526 //      Process messages that needed to wait until a frame had gone by.
527 void process_pending_messages(void)
528 {
529         int     i;
530
531         for (i=0; i<MAX_PENDING_MESSAGES; i++)
532                 if (Pending_messages[i].frame_to_process != -1)
533                         if (Pending_messages[i].frame_to_process <= FrameCount) {
534                                 pending_message *pmp = &Pending_messages[i];
535                                 PostMessage((HWND) pmp->hwnd, pmp->id, pmp->wparam, pmp->lparam);
536                                 Pending_messages[i].frame_to_process = -1;
537                         }
538 }
539
540 //      Add a message to be processed to a buffer.
541 //      Wait skip_count frames before processing.
542 void add_pending_message(HWND hwnd, int id, int wparam, int lparam, int skip_count)
543 {
544         int     i;
545
546         for (i=0; i<MAX_PENDING_MESSAGES; i++)
547                 if (Pending_messages[i].frame_to_process == -1) {
548                         Pending_messages[i].hwnd = (int) hwnd;
549                         Pending_messages[i].id = id;
550                         Pending_messages[i].wparam = wparam;
551                         Pending_messages[i].lparam = lparam;
552                         Pending_messages[i].frame_to_process = FrameCount + skip_count;
553                 }
554 }
555
556 void init_pending_messages(void)
557 {
558         int     i;
559
560         for (i=0; i<MAX_PENDING_MESSAGES; i++)
561                 Pending_messages[i].frame_to_process = -1;
562 }
563
564 // void win32_blit(HDC hSrcDC, HPALETTE hPalette, int x, int y, int w, int h )
565 #if 0
566 void win32_blit(void *xx, void *yy, int x, int y, int w, int h )
567 {
568         HPALETTE hOldPalette = NULL;
569         HDC hdc = GetDC(hwndApp);
570
571         if ( !hdc )     return;
572         if ( !fAppActive ) return;
573
574         if (hPalette)   {
575                 hOldPalette = SelectPalette(hdc, hPalette, FALSE);
576                 RealizePalette( hdc );
577         }
578
579         BitBlt(hdc, 0, 0, w, h, hSrcDC, x, y, SRCCOPY);
580         
581         if ( hOldPalette )      
582                 SelectPalette(hdc, hOldPalette, FALSE);
583
584         ReleaseDC( hwndApp, hdc );
585 }
586 #endif
587
588 void draw_render_window(CDC* pDC)
589 {
590         int w, h;
591
592         w = gr_screen.clip_width;
593         h = gr_screen.clip_height;
594         gr_screen.clip_width = gr_screen.max_w;
595         gr_screen.clip_height = gr_screen.max_h;
596         gr_flip_window((uint) pDC->m_hDC, 0, 0, gr_screen.max_w, gr_screen.max_h);
597         gr_screen.clip_width = w;
598         gr_screen.clip_height = h;
599 }
600
601 BOOL CFREDApp::OnIdle(LONG lCount)
602 {
603         int adjust = 0;
604         CWnd *top, *wnd;
605
606         if (!Show_sexp_help)
607                 adjust = -SEXP_HELP_BOX_SIZE;
608
609         if (!app_init) {
610                 app_init = 1;
611                 theApp.init_window(&Ship_wnd_data, &Ship_editor_dialog, adjust, 1);
612                 theApp.init_window(&Wing_wnd_data, &Wing_editor_dialog, adjust, 1);
613                 theApp.init_window(&Waypoint_wnd_data, &Waypoint_editor_dialog, 0, 1);
614                 init_window(&Main_wnd_data, Fred_main_wnd);
615                 Fred_main_wnd->SetWindowPos(&CWnd::wndTop, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
616
617                 Ship_editor_dialog.calc_cue_height();
618                 Wing_editor_dialog.calc_cue_height();
619         }
620
621         CWinApp::OnIdle(lCount);
622         internal_integrity_check();
623         if (Update_ship) {
624                 Ship_editor_dialog.initialize_data(1);
625                 Update_ship = 0;
626         }
627
628         if (Update_wing) {
629                 Wing_editor_dialog.initialize_data(1);
630                 Update_wing = 0;
631         }
632
633         Prev_window = CFREDView::GetActiveWindow();
634
635         // Find the root window of the active window
636         wnd = top = Prev_window;
637         while (wnd) {
638                 top = wnd;
639                 wnd = wnd->GetParent();
640         }
641
642         // See if the active window is a child of Fred
643         if (Prev_window)
644                 Fred_active = ( (top == Fred_main_wnd) || (top == Campaign_wnd) );
645         else
646                 Fred_active = 0;
647
648         if (!Fred_active)
649                 return FALSE;  // if fred isn't active, don't waste any time with it.
650
651         game_do_frame();  // do stuff that needs doing, whether we render or not.
652         show_control_mode();
653
654         if (!Update_window)
655                 return FALSE;
656
657         render_frame(); // "do the rendering!"  Renders image to offscreen buffer
658
659         CFREDView* pFV = CFREDView::GetView();
660         CDC* pDC = pFV->GetDC();
661
662         // gr_surface_flip();
663
664         // if you hit the next Assert, find Hoffoss or Allender.  If neither here, then comment it out.
665         Assert( Update_window >= 0 );
666         if (Update_window) {
667                 draw_render_window(pDC);  // this actually copies the offscreen buffer to the screen
668                 Update_window--;
669         }
670
671         process_pending_messages();
672         pFV->ReleaseDC(pDC);
673
674         FrameCount++;
675         return TRUE;
676 }
677
678 void update_map_window()
679 {
680         if (Fred_active) {
681                 Update_window++;  // on idle will handle the drawing already.
682                 return;
683         }
684
685         if (!Fred_main_wnd)
686                 return;
687
688         CFREDView* pFV = CFREDView::GetView();
689         if (!pFV)
690                 return;
691
692         render_frame(); // "do the rendering!"
693
694         CDC* pDC = pFV->GetDC();
695         Assert(pDC);
696
697         draw_render_window(pDC);
698         if ( Update_window > 0 )
699                 Update_window--;
700
701         show_control_mode();
702         process_pending_messages();
703         pFV->ReleaseDC(pDC);
704
705         FrameCount++;
706 }
707
708 void CFREDApp::write_ini_file(int degree)
709 {
710         WriteProfileInt("Preferences", "User interface", User_interface);
711         WriteProfileInt("Preferences", "Show stars", Show_stars);
712         WriteProfileInt("Preferences", "Show grid positions", Show_grid_positions);
713         WriteProfileInt("Preferences", "Show coordinates", Show_coordinates);
714         WriteProfileInt("Preferences", "Show compass", Show_compass);
715         WriteProfileInt("Preferences", "Show ship models", Show_ship_models);
716         WriteProfileInt("Preferences", "Show ship info", Show_ship_info);
717         WriteProfileInt("Preferences", "Show outlines", Show_outlines);
718         WriteProfileInt("Preferences", "Physics speed", physics_speed);
719         WriteProfileInt("Preferences", "Physics rotation", physics_rot);
720         WriteProfileInt("Preferences", "Show waypoints", Show_waypoints);
721         WriteProfileInt("Preferences", "Show sexp help", Show_sexp_help);
722         WriteProfileInt("Preferences", "Hide ship cues", Hide_ship_cues);
723         WriteProfileInt("Preferences", "Hide wing cues", Hide_wing_cues);
724         WriteProfileInt("Preferences", "Autosave disabled", Autosave_disabled);
725         WriteProfileInt("Preferences", "Double fine gridlines", double_fine_gridlines);
726         WriteProfileInt("Preferences", "Anti aliased gridlines", Aa_gridlines);
727         WriteProfileInt("Preferences", "Show dock points",      Show_dock_points);
728         WriteProfileInt("Preferences", "Show paths",    Show_paths_fred);
729
730         if (!degree) {
731                 record_window_data(&Waypoint_wnd_data, &Waypoint_editor_dialog);
732                 record_window_data(&Wing_wnd_data, &Wing_editor_dialog);
733                 record_window_data(&Ship_wnd_data, &Ship_editor_dialog);
734                 record_window_data(&Main_wnd_data, Fred_main_wnd);
735
736                 write_window("Main window", &Main_wnd_data);
737                 write_window("Ship window", &Ship_wnd_data);
738                 write_window("Wing window", &Wing_wnd_data);
739                 write_window("Waypoint window", &Waypoint_wnd_data);
740                 write_window("Object window", &Object_wnd_data);
741                 write_window("Mission goals window", &Mission_goals_wnd_data);
742                 write_window("Messages window", &Messages_wnd_data);
743                 write_window("Player window", &Player_wnd_data);
744                 write_window("Events window", &Events_wnd_data);
745                 write_window("Bg window", &Bg_wnd_data);
746                 write_window("Briefing window", &Briefing_wnd_data);
747                 write_window("Reinforcement window", &Reinforcement_wnd_data);
748                 write_window("Starfield window", &Starfield_wnd_data);
749                 write_window("Asteroid window", &Asteroid_wnd_data);
750                 write_window("Mission notes window", &Mission_notes_wnd_data);
751         }
752 }
753
754 void CFREDApp::write_window(char *name, window_data *wndd)
755 {
756         WriteProfileInt(name, "valid", wndd->valid);
757         WriteProfileInt(name, "length", wndd->p.length);
758         WriteProfileInt(name, "flags", wndd->p.flags);
759         WriteProfileInt(name, "showCmd", wndd->p.showCmd);
760         WriteProfileInt(name, "ptMinPosition.x", wndd->p.ptMinPosition.x);
761         WriteProfileInt(name, "ptMinPosition.y", wndd->p.ptMinPosition.y);
762         WriteProfileInt(name, "ptMaxPosition.x", wndd->p.ptMaxPosition.x);
763         WriteProfileInt(name, "ptMaxPosition.y", wndd->p.ptMaxPosition.y);
764         WriteProfileInt(name, "rcNormalPosition.left", wndd->p.rcNormalPosition.left);
765         WriteProfileInt(name, "rcNormalPosition.top", wndd->p.rcNormalPosition.top);
766         WriteProfileInt(name, "rcNormalPosition.right", wndd->p.rcNormalPosition.right);
767         WriteProfileInt(name, "rcNormalPosition.bottom", wndd->p.rcNormalPosition.bottom);
768         WriteProfileInt(name, "Visible", wndd->visible);
769 }
770
771 void CFREDApp::read_window(char *name, window_data *wndd)
772 {
773         wndd->processed = 0;
774         wndd->valid = GetProfileInt(name, "valid", FALSE);
775         wndd->p.length = GetProfileInt(name, "length", 0);
776         wndd->p.flags = GetProfileInt(name, "flags", 0);
777         wndd->p.showCmd = GetProfileInt(name, "showCmd", SW_SHOWMAXIMIZED);
778         wndd->p.ptMinPosition.x = GetProfileInt(name, "ptMinPosition.x", 0);
779         wndd->p.ptMinPosition.y = GetProfileInt(name, "ptMinPosition.y", 0);
780         wndd->p.ptMaxPosition.x = GetProfileInt(name, "ptMaxPosition.x", 0);
781         wndd->p.ptMaxPosition.y = GetProfileInt(name, "ptMaxPosition.y", 0);
782         wndd->p.rcNormalPosition.left = GetProfileInt(name, "rcNormalPosition.left", 0);
783         wndd->p.rcNormalPosition.top = GetProfileInt(name, "rcNormalPosition.top", 0);
784         wndd->p.rcNormalPosition.right = GetProfileInt(name, "rcNormalPosition.right", 0);
785         wndd->p.rcNormalPosition.bottom = GetProfileInt(name, "rcNormalPosition.bottom", 0);
786         wndd->visible = GetProfileInt(name, "Visible", 1);
787 }
788
789 int CFREDApp::init_window(window_data *wndd, CWnd *wnd, int adjust, int pre)
790 {
791         int width, height;
792         WINDOWPLACEMENT p;
793
794         if (pre && !wndd->visible)
795                 return -1;
796
797         if (wndd->processed)
798                 return -2;
799
800         Assert(wnd->GetSafeHwnd());
801         wnd->GetWindowPlacement(&p);
802         width = p.rcNormalPosition.right - p.rcNormalPosition.left;
803         height = p.rcNormalPosition.bottom - p.rcNormalPosition.top + adjust;
804         wndd->p.rcNormalPosition.right = wndd->p.rcNormalPosition.left + width;
805         wndd->p.rcNormalPosition.bottom = wndd->p.rcNormalPosition.top + height;
806
807         if (wndd->valid) {
808                 wnd->SetWindowPlacement(&wndd->p);
809 //              if (!wndd->visible)
810 //                      wnd->ShowWindow(SW_SHOW);
811 //              else
812 //                      wnd->ShowWindow(SW_HIDE);
813         }
814
815         record_window_data(wndd, wnd);
816         wndd->processed = 1;
817         return 0;
818 }
819
820 void CFREDApp::record_window_data(window_data *wndd, CWnd *wnd)
821 {
822         wnd->GetWindowPlacement(&wndd->p);
823         wndd->visible = wnd->IsWindowVisible();
824         wndd->valid = TRUE;
825 }
826