]> icculus.org git repositories - taylor/freespace2.git/blob - src/pofview/pofview.cpp
Initial revision
[taylor/freespace2.git] / src / pofview / pofview.cpp
1 // PofView.cpp : Defines the class behaviors for the application.
2 //
3
4 #include "stdafx.h"
5 #include "pofview.h"
6
7 #include "mainfrm.h"
8 #include "childfrm.h"
9 #include "pofviewdoc.h"
10 #include "pofviewview.h"
11
12 #include "pstypes.h"
13 #include "cfile.h"
14 #include "palman.h"
15 #include "2d.h"
16 #include "3d.h"
17 #include "model.h"
18 #include "vecmat.h"
19 #include "floating.h"
20 #include "key.h"
21 #include "timer.h"
22 #include "mouse.h"
23 #include "bmpman.h"
24 #include "systemvars.h"
25
26
27 #ifdef _DEBUG
28 #define new DEBUG_NEW
29 #undef THIS_FILE
30 static char THIS_FILE[] = __FILE__;
31 #endif
32
33 int Pofview_running = 1;
34
35 /////////////////////////////////////////////////////////////////////////////
36 // CPofViewApp
37
38 BEGIN_MESSAGE_MAP(CPofViewApp, CWinApp)
39         //{{AFX_MSG_MAP(CPofViewApp)
40         ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
41                 // NOTE - the ClassWizard will add and remove mapping macros here.
42                 //    DO NOT EDIT what you see in these blocks of generated code!
43         //}}AFX_MSG_MAP
44         // Standard file based document commands
45         ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
46         ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
47         // Standard print setup command
48         ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)
49 END_MESSAGE_MAP()
50
51 /////////////////////////////////////////////////////////////////////////////
52 // CPofViewApp construction
53
54 CPofViewApp::CPofViewApp()
55 {
56         // TODO: add construction code here,
57         // Place all significant initialization in InitInstance
58 }
59
60 /////////////////////////////////////////////////////////////////////////////
61 // The one and only CPofViewApp object
62
63 CPofViewApp theApp;
64
65 /////////////////////////////////////////////////////////////////////////////
66 // CPofViewApp initialization
67
68 BOOL CPofViewApp::InitInstance()
69 {
70         // Standard initialization
71         // If you are not using these features and wish to reduce the size
72         //  of your final executable, you should remove from the following
73         //  the specific initialization routines you do not need.
74
75 #ifdef _AFXDLL
76         Enable3dControls();                     // Call this when using MFC in a shared DLL
77 #else
78         Enable3dControlsStatic();       // Call this when linking to MFC statically
79 #endif
80
81         LoadStdProfileSettings();  // Load standard INI file options (including MRU)
82
83         // Register the application's document templates.  Document templates
84         //  serve as the connection between documents, frame windows and views.
85
86         CMultiDocTemplate* pDocTemplate;
87         pDocTemplate = new CMultiDocTemplate(
88                 IDR_POFTYPE,
89                 RUNTIME_CLASS(CPofViewDoc),
90                 RUNTIME_CLASS(CChildFrame), // custom MDI child frame
91                 RUNTIME_CLASS(CPofViewView));
92         AddDocTemplate(pDocTemplate);
93
94         // create main MDI Frame window
95         CMainFrame* pMainFrame = new CMainFrame;
96         if (!pMainFrame->LoadFrame(IDR_MAINFRAME))
97                 return FALSE;
98         m_pMainWnd = pMainFrame;
99
100         // Enable drag/drop open
101         m_pMainWnd->DragAcceptFiles();
102
103         // setup the fred exe directory so CFILE can init properly
104         /*
105         char *c = GetCommandLine();
106         Assert(c != NULL);
107         char *tok = strtok(c, " ");
108         Assert(tok != NULL);    
109         */
110
111         outwnd_init();
112         timer_init();
113         cfile_init(__argv[0]);
114         palette_load_table( "gamepalette1-01" );
115         gr_init(GR_640, GR_SOFTWARE, 8, 640, 480);
116         gr_set_gamma(2.0f);
117         key_init();
118         mouse_init();
119         gr_init_font( "font01.vf" );
120         m_timer = timer_get_milliseconds();
121         model_init();
122
123         // Enable DDE Execute open
124         EnableShellOpen();
125         RegisterShellFileTypes(TRUE);
126
127         // Parse command line for standard shell commands, DDE, file open
128         CCommandLineInfo cmdInfo;
129         ParseCommandLine(cmdInfo);
130
131         // DON'T display a new MDI child window during startup!!!
132         if ( cmdInfo.m_nShellCommand == CCommandLineInfo::FileNew )     {
133                 cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing;
134         }
135
136         // Dispatch commands specified on the command line
137         if (!ProcessShellCommand(cmdInfo))
138                 return FALSE;
139
140         // The main window has been initialized, so show and update it.
141         pMainFrame->ShowWindow(m_nCmdShow);
142         pMainFrame->UpdateWindow();
143
144         return TRUE;
145 }
146
147 /////////////////////////////////////////////////////////////////////////////
148 // CAboutDlg dialog used for App About
149
150 class CAboutDlg : public CDialog
151 {
152 public:
153         CAboutDlg();
154
155 // Dialog Data
156         //{{AFX_DATA(CAboutDlg)
157         enum { IDD = IDD_ABOUTBOX };
158         //}}AFX_DATA
159
160         // ClassWizard generated virtual function overrides
161         //{{AFX_VIRTUAL(CAboutDlg)
162         protected:
163         virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
164         //}}AFX_VIRTUAL
165
166 // Implementation
167 protected:
168         //{{AFX_MSG(CAboutDlg)
169                 // No message handlers
170         //}}AFX_MSG
171         DECLARE_MESSAGE_MAP()
172 };
173
174 CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
175 {
176         //{{AFX_DATA_INIT(CAboutDlg)
177         //}}AFX_DATA_INIT
178 }
179
180 void CAboutDlg::DoDataExchange(CDataExchange* pDX)
181 {
182         CDialog::DoDataExchange(pDX);
183         //{{AFX_DATA_MAP(CAboutDlg)
184         //}}AFX_DATA_MAP
185 }
186
187 BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
188         //{{AFX_MSG_MAP(CAboutDlg)
189                 // No message handlers
190         //}}AFX_MSG_MAP
191 END_MESSAGE_MAP()
192
193 // App command to run the dialog
194 void CPofViewApp::OnAppAbout()
195 {
196         CAboutDlg aboutDlg;
197         aboutDlg.DoModal();
198 }
199
200 /////////////////////////////////////////////////////////////////////////////
201 // CPofViewApp commands
202
203
204 CPofViewView * GetView()
205 {
206   CMDIChildWnd * pChild =
207        ((CMDIFrameWnd*)(AfxGetApp()->m_pMainWnd))->MDIGetActive();
208
209   if ( !pChild )
210      return NULL;
211
212   CView * pView = pChild->GetActiveView();
213
214   if ( !pView )
215      return NULL;
216
217   // Fail if view is of wrong kind
218   // (this could occur with splitter windows, or additional
219   // views on a single document
220   if ( ! pView->IsKindOf( RUNTIME_CLASS(CPofViewView) ) )
221      return NULL;
222
223   return (CPofViewView *) pView;
224 }
225
226
227 // Stuff for showing ship thrusters. 
228 typedef struct thrust_anim {
229         int     num_frames;
230         int     first_frame;
231         float time;                             // in seconds
232 } thrust_anim;
233
234 #define NUM_THRUST_ANIMS                                        6
235 #define THRUST_ANIM_NORMAL                                      0
236 #define THRUST_ANIM_AFTERBURNER                 1
237 #define THRUST_ANIM_GLOW_NORMAL                 2
238 #define THRUST_ANIM_GLOW_AFTERBURNER    3
239
240 static thrust_anim      Thrust_anims[NUM_THRUST_ANIMS];
241 extern char Thrust_anim_names[NUM_THRUST_ANIMS][MAX_FILENAME_LEN];
242
243 static int Thrust_anim_inited = 0;
244
245 int     shipp_thruster_bitmap = -1;                                     // What frame the current thruster bitmap is at for this ship
246 float   shipp_thruster_frame = 0.0f;                                    // Used to keep track of which frame the animation should be on.
247
248 int     shipp_thruster_glow_bitmap = -1;                                        // What frame the current thruster bitmap is at for this ship
249 float   shipp_thruster_glow_frame = 0.0f;                                       // Used to keep track of which frame the animation should be on.
250 float   shipp_thruster_glow_noise = 1.0f;
251
252 // loads the animations for ship's afterburners
253 void init_thrusters()
254 {
255         int                     fps, i;
256         thrust_anim     *ta;
257
258         if ( Thrust_anim_inited == 1 )
259                 return;
260
261         for ( i = 0; i < NUM_THRUST_ANIMS; i++ ) {
262                 ta = &Thrust_anims[i];
263                 //if ( i < 2 )  {
264                         ta->first_frame = bm_load_animation(Thrust_anim_names[i],  &ta->num_frames, &fps);
265                         if ( ta->first_frame == -1 ) {
266                                 Error(LOCATION,"Error loading animation file: %s\n",Thrust_anim_names[i]);
267                                 return;
268                         }
269                         Assert(fps != 0);
270                         ta->time = i2fl(ta->num_frames)/fps;
271                 //} else {
272                 //      ta->first_frame = bm_load(Thrust_anim_names[i] );
273                 //      ta->num_frames = NOISE_NUM_FRAMES;
274                 //      fps = 15;
275                 //      if ( ta->first_frame == -1 ) {
276                 //              Error(LOCATION,"Error loading bitmap file: %s\n",Thrust_anim_names[i]);
277                 //              return;
278                 //      }
279                 //      Assert(fps != 0);
280                 //      ta->time = i2fl(ta->num_frames)/fps;
281                 //}
282         }
283
284         Thrust_anim_inited = 1;
285 }
286
287         // JAS - figure out which thruster bitmap will get rendered next
288         // time around.  ship_render needs to have shipp_thruster_bitmap set to
289         // a valid bitmap number, or -1 if we shouldn't render thrusters.
290 void do_thruster_frame( float thrust, int afterburner, float frametime )
291 {
292         float rate;
293         int framenum;
294         thrust_anim *the_anim;
295
296         if ( !Thrust_anim_inited )      init_thrusters();
297
298         if ( afterburner )      {
299                 the_anim = &Thrust_anims[THRUST_ANIM_AFTERBURNER];
300                 rate = 1.2f;            // go at 1.2x faster when afterburners on
301         } else {
302                 the_anim = &Thrust_anims[THRUST_ANIM_NORMAL];
303                 // If thrust at 0, go at half as fast, full thrust; full framerate
304                 // so set rate from 0.5 to 1.0, depending on thrust from 0 to 1
305                 rate = 0.5f + thrust / 2.0f;
306         }
307
308         shipp_thruster_frame += frametime * rate;
309
310         // Sanity checks
311         if ( shipp_thruster_frame < 0.0f )      shipp_thruster_frame = 0.0f;
312         if ( shipp_thruster_frame > 100.0f ) shipp_thruster_frame = 0.0f;
313
314         if ( shipp_thruster_frame > the_anim->time )    {
315                 shipp_thruster_frame -= the_anim->time;
316         }
317         framenum = fl2i( (shipp_thruster_frame*the_anim->num_frames) / the_anim->time );
318         if ( framenum < 0 ) framenum = 0;
319         if ( framenum >= the_anim->num_frames ) framenum = the_anim->num_frames-1;
320         
321         // Get the bitmap for this frame
322         shipp_thruster_bitmap = the_anim->first_frame + framenum;
323
324 //      mprintf(( "TF: %.2f\n", shipp_thruster_frame ));
325
326
327         // Do for glows
328
329         if ( afterburner )      {
330                 the_anim = &Thrust_anims[THRUST_ANIM_GLOW_AFTERBURNER];
331                 rate = 1.2f;            // go at 1.2x faster when afterburners on
332         } else {
333                 the_anim = &Thrust_anims[THRUST_ANIM_GLOW_NORMAL];
334                 // If thrust at 0, go at half as fast, full thrust; full framerate
335                 // so set rate from 0.5 to 1.0, depending on thrust from 0 to 1
336                 rate = 0.5f + thrust / 2.0f;
337         }
338
339         shipp_thruster_glow_frame += frametime * rate;
340
341         // Sanity checks
342         if ( shipp_thruster_glow_frame < 0.0f ) shipp_thruster_glow_frame = 0.0f;
343         if ( shipp_thruster_glow_frame > 100.0f ) shipp_thruster_glow_frame = 0.0f;
344
345         if ( shipp_thruster_glow_frame > the_anim->time )       {
346                 shipp_thruster_glow_frame -= the_anim->time;
347         }
348         framenum = fl2i( (shipp_thruster_glow_frame*the_anim->num_frames) / the_anim->time );
349         if ( framenum < 0 ) framenum = 0;
350         if ( framenum >= the_anim->num_frames ) framenum = the_anim->num_frames-1;
351         
352         // Get the bitmap for this frame
353         shipp_thruster_glow_bitmap = the_anim->first_frame;
354         shipp_thruster_glow_noise = Noise[framenum];
355
356 //      mprintf(( "TF: %.2f\n", shipp_thruster_frame ));
357
358 }
359
360
361 int pofview_focus=0;
362 float flFrametime;
363
364 float model_thrust = 0.0f;
365 int model_afterburner = 0;
366
367 BOOL CPofViewApp::OnIdle(LONG lCount)
368 {
369         CWinApp::OnIdle(lCount);
370
371         CPofViewView* CurrentView;
372         CDC* pDC;
373         int tmp_time = timer_get_milliseconds();
374         float frame_time;
375         int k = key_inkey();
376
377         frame_time = ((float)(tmp_time-m_timer)) / 1000.0f;
378         flFrametime = frame_time;
379
380         m_timer = tmp_time;
381
382         if (pofview_focus<1) return FALSE;
383
384         CurrentView = GetView();
385         if ( !CurrentView ) return TRUE;
386
387         do_thruster_frame( model_thrust, model_afterburner, flFrametime );
388
389         CurrentView->MoveViewer(frame_time,TRUE,k);
390
391         pDC = CurrentView->GetDC();
392         if ( !pDC ) return TRUE;
393
394         CurrentView->OnDraw(pDC);
395
396         CurrentView->ReleaseDC(pDC);
397
398         return TRUE;
399 }
400
401 int CPofViewApp::ExitInstance() 
402 {
403         // TODO: Add your specialized code here and/or call the base class
404         
405         return CWinApp::ExitInstance();
406 }