]> icculus.org git repositories - taylor/freespace2.git/blob - src/pofview/pofview.cpp
merge in some code cleanup
[taylor/freespace2.git] / src / pofview / pofview.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 // PofView.cpp : Defines the class behaviors for the application.
10 //
11
12 #include "pofview.h"
13
14 #include "wx/filename.h"
15
16 #include "pstypes.h"
17 #include "2d.h"
18 #include "bmpman.h"
19 #include "systemvars.h"
20 #include "model.h"
21 #include "cfile.h"
22 #include "timer.h"
23 #include "key.h"
24 #include "mouse.h"
25
26 #include "res/pofview_ico.xpm"
27 #include "res/tool_about.xpm"
28 #include "res/tool_damaged.xpm"
29 #include "res/tool_debris.xpm"
30 #include "res/tool_detail1.xpm"
31 #include "res/tool_detail2.xpm"
32 #include "res/tool_detail3.xpm"
33 #include "res/tool_detail4.xpm"
34 #include "res/tool_detail5.xpm"
35 #include "res/tool_detail6.xpm"
36 #include "res/tool_lights.xpm"
37 #include "res/tool_tree.xpm"
38
39
40 int Pofview_running = 1;
41
42 bool in_dialog = false;
43
44
45 class PofViewApp: public wxApp
46 {
47         public:
48                 virtual bool OnInit();
49 };
50
51
52 IMPLEMENT_APP(PofViewApp)
53
54 bool PofViewApp::OnInit()
55 {
56         PofViewFrame *frame = new PofViewFrame(NULL);
57         frame->Show(true);
58         SetTopWindow(frame);
59
60         return true;
61 }
62
63 BEGIN_EVENT_TABLE( PofViewFrame, wxFrame )
64         EVT_MENU( wxID_OPEN, PofViewFrame::OnFileOpen )
65         EVT_MENU( wxID_CLOSE, PofViewFrame::OnFileClose )
66         EVT_MENU( wxID_EXIT, PofViewFrame::OnExit )
67         EVT_MENU( ID_M_VIEW_TOOLBAR, PofViewFrame::OnViewToolbar )
68         EVT_MENU( ID_M_VIEW_STATUSBAR, PofViewFrame::OnViewStatusBar )
69         EVT_MENU( wxID_ABOUT, PofViewFrame::OnHelpAbout )
70         EVT_TOOL( ID_M_TOOLABOUT, PofViewFrame::OnHelpAbout )
71         EVT_TOOL_RANGE( ID_M_TOOLDEBRIS, ID_M_TOOLDETAIL6, PofViewFrame::OnSetDetail )
72         EVT_TOOL( ID_M_TOOLSHOWTREE, PofViewFrame::OnShowTree )
73 END_EVENT_TABLE()
74
75 PofViewFrame::PofViewFrame( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style )
76         : wxFrame( parent, id, title, pos, size, style )
77 {
78         m_model_num = -1;
79         m_glContext = NULL;
80         m_canvas = NULL;
81
82         pofview_initted = false;
83
84         this->SetSizeHints( wxSize( 640,480 ), wxDefaultSize );
85
86         this->SetIcon(wxICON(pofview_ico));
87
88         MakeMenuBar();
89         MakeToolBar();
90
91         SetToolDefaults();
92
93         this->Show(true);
94
95         m_statusBar1 = this->CreateStatusBar( 1, wxSTB_DEFAULT_STYLE, wxID_ANY );
96
97         this->Centre( wxBOTH );
98 }
99
100 PofViewFrame::~PofViewFrame()
101 {
102         if (m_glContext) {
103                 delete m_glContext;
104         }
105 }
106
107 void PofViewFrame::MakeMenuBar()
108 {
109         m_menubar1 = new wxMenuBar( 0 );
110
111         // 'File' menu
112         m_menuFile = new wxMenu();
113
114         m_menuFile->Append( wxID_OPEN );
115         m_menuFile->Append( wxID_CLOSE );
116
117         m_menuFile->AppendSeparator();
118
119         m_menuFile->Append( wxID_EXIT );
120
121         m_menubar1->Append( m_menuFile, wxT("File") );
122
123         // 'View' menu
124         m_menuView = new wxMenu();
125
126         m_menuView->AppendCheckItem( ID_M_VIEW_TOOLBAR, "&Toolbar", "Show or hide the toolbar" );
127         m_menuView->AppendCheckItem( ID_M_VIEW_STATUSBAR, "&Status Bar", "Show or hide the status bar" );
128
129         m_menuView->Check( ID_M_VIEW_TOOLBAR, true );
130         m_menuView->Check( ID_M_VIEW_STATUSBAR, true );
131
132         m_menuView->AppendSeparator();
133
134         m_menuView->AppendCheckItem( ID_M_VIEW_OUTLINE, "&Outline", "Toggles outline mode" );
135         m_menuView->AppendCheckItem( ID_M_VIEW_LIGHTING, "&Lighting", "Toggle lighting" );
136         m_menuView->AppendCheckItem( ID_M_VIEW_PIVTOS, "&Pivots/Bounding Boxes", "Toggle pivots and bounding boxes" );
137         m_menuView->AppendCheckItem( ID_M_VIEW_PATHS, "P&aths", "Show all the paths" );
138         m_menuView->AppendCheckItem( ID_M_VIEW_RADIUS, "&Radius", "Show the object's radius." );
139         m_menuView->AppendCheckItem( ID_M_VIEW_THRUSTERS, "T&hrusters", "Toggles thrusters" );
140         m_menuView->AppendCheckItem( ID_M_VIEW_TEXTURING, "Texturing" );
141         m_menuView->AppendCheckItem( ID_M_VIEW_SMOOTHING, "Smoothing" );
142         m_menuView->AppendCheckItem( ID_M_VIEW_SHIELDS, "Shields" );
143         m_menuView->AppendCheckItem( ID_M_VIEW_INVISIBLE, "Invisible Faces" );
144         m_menuView->AppendCheckItem( ID_M_VIEW_BAYPATHS, "Bay Paths" );
145         m_menuView->AppendCheckItem( ID_M_VIEW_AUTOCENTER, "Autocenter" );
146
147         m_menubar1->Append( m_menuView, wxT("View") );
148
149         // 'Help' menu
150         m_menuHelp = new wxMenu();
151
152         m_menuHelp->Append( wxID_ABOUT, "&About PofView...");
153
154         m_menubar1->Append( m_menuHelp, wxT("Help") );
155
156
157         this->SetMenuBar( m_menubar1 );
158 }
159
160 void PofViewFrame::MakeToolBar()
161 {
162         m_toolBar1 = this->CreateToolBar( wxTB_HORIZONTAL, wxID_ANY );
163
164         m_toolBar1->AddTool( wxID_OPEN, wxEmptyString, wxArtProvider::GetBitmap( wxART_FILE_OPEN, wxART_TOOLBAR ), wxNullBitmap, wxITEM_NORMAL, wxT("Open an existing document"), wxEmptyString, NULL );
165
166         m_toolBar1->AddSeparator();
167
168         m_toolBar1->AddTool( ID_M_TOOLABOUT, wxEmptyString, wxBitmap( tool_about_xpm ), wxNullBitmap, wxITEM_NORMAL, wxT("Display program information, version number and copyright"), wxEmptyString, NULL );
169
170         m_toolBar1->AddSeparator();
171
172         m_toolBar1->AddTool( ID_M_TOOLDEBRIS, wxEmptyString, wxBitmap( tool_debris_xpm ), wxNullBitmap, wxITEM_CHECK, wxT("Show debris pieces"), wxEmptyString, NULL );
173         m_toolBar1->AddTool( ID_M_TOOLDETAIL1, wxEmptyString, wxBitmap( tool_detail1_xpm ), wxNullBitmap, wxITEM_CHECK, wxT("Set to Detail Level 1"), wxEmptyString, NULL );
174         m_toolBar1->AddTool( ID_M_TOOLDETAIL2, wxEmptyString, wxBitmap( tool_detail2_xpm ), wxNullBitmap, wxITEM_CHECK, wxT("Set to Detail Level 2"), wxEmptyString, NULL );
175         m_toolBar1->AddTool( ID_M_TOOLDETAIL3, wxEmptyString, wxBitmap( tool_detail3_xpm ), wxNullBitmap, wxITEM_CHECK, wxT("Set to Detail Level 3"), wxEmptyString, NULL );
176         m_toolBar1->AddTool( ID_M_TOOLDETAIL4, wxEmptyString, wxBitmap( tool_detail4_xpm ), wxNullBitmap, wxITEM_CHECK, wxT("Set to Detail Level 4"), wxEmptyString, NULL );
177         m_toolBar1->AddTool( ID_M_TOOLDETAIL5, wxEmptyString, wxBitmap( tool_detail5_xpm ), wxNullBitmap, wxITEM_CHECK, wxT("Set to Detail Level 5"), wxEmptyString, NULL );
178         m_toolBar1->AddTool( ID_M_TOOLDETAIL6, wxEmptyString, wxBitmap( tool_detail6_xpm ), wxNullBitmap, wxITEM_CHECK, wxT("Set to Detail Level 6"), wxEmptyString, NULL );
179
180         m_toolBar1->AddSeparator();
181
182         m_toolBar1->AddTool( ID_M_TOOLSHOWTREE, wxEmptyString, wxBitmap( tool_tree_xpm ), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString, NULL );
183         m_toolBar1->AddTool( ID_M_TOOLSHOWDAMAGED, wxEmptyString, wxBitmap( tool_damaged_xpm ), wxNullBitmap, wxITEM_CHECK, wxT("Toggles damaged subobjects on/off"), wxEmptyString, NULL );
184
185         m_toolBar1->AddSeparator();
186
187         m_toolBar1->AddTool( ID_M_TOOLTOGGLELIGHTS, wxEmptyString, wxBitmap( tool_lights_xpm ), wxNullBitmap, wxITEM_CHECK, wxT("Toggles lights"), wxEmptyString, NULL );
188
189         m_toolBar1->Realize();
190 }
191
192 void PofViewFrame::SetToolDefaults()
193 {
194         m_toolBar1->EnableTool( ID_M_TOOLDEBRIS, false );
195         m_toolBar1->EnableTool( ID_M_TOOLDETAIL1, false );
196         m_toolBar1->EnableTool( ID_M_TOOLDETAIL2, false );
197         m_toolBar1->EnableTool( ID_M_TOOLDETAIL3, false );
198         m_toolBar1->EnableTool( ID_M_TOOLDETAIL4, false );
199         m_toolBar1->EnableTool( ID_M_TOOLDETAIL5, false );
200         m_toolBar1->EnableTool( ID_M_TOOLDETAIL6, false );
201
202         m_toolBar1->ToggleTool( ID_M_TOOLDEBRIS, false );
203         m_toolBar1->ToggleTool( ID_M_TOOLDETAIL1, false );
204         m_toolBar1->ToggleTool( ID_M_TOOLDETAIL2, false );
205         m_toolBar1->ToggleTool( ID_M_TOOLDETAIL3, false );
206         m_toolBar1->ToggleTool( ID_M_TOOLDETAIL4, false );
207         m_toolBar1->ToggleTool( ID_M_TOOLDETAIL5, false );
208         m_toolBar1->ToggleTool( ID_M_TOOLDETAIL6, false );
209
210         m_toolBar1->EnableTool( ID_M_TOOLSHOWTREE, false );
211         m_toolBar1->EnableTool( ID_M_TOOLSHOWDAMAGED, false );
212
213         m_toolBar1->ToggleTool( ID_M_TOOLSHOWDAMAGED, false );
214
215         m_toolBar1->EnableTool( ID_M_TOOLTOGGLELIGHTS, false );
216
217         m_toolBar1->ToggleTool( ID_M_TOOLTOGGLELIGHTS, true );
218
219         m_menuFile->Enable( wxID_CLOSE, false );
220
221         m_menuView->Enable( ID_M_VIEW_OUTLINE, false );
222         m_menuView->Enable( ID_M_VIEW_LIGHTING, false );
223         m_menuView->Enable( ID_M_VIEW_PIVTOS, false );
224         m_menuView->Enable( ID_M_VIEW_PATHS, false );
225         m_menuView->Enable( ID_M_VIEW_RADIUS, false );
226         m_menuView->Enable( ID_M_VIEW_THRUSTERS, false );
227
228         m_menuView->Check( ID_M_VIEW_OUTLINE, false );
229         m_menuView->Check( ID_M_VIEW_LIGHTING, false );
230         m_menuView->Check( ID_M_VIEW_PIVTOS, false );
231         m_menuView->Check( ID_M_VIEW_PATHS, false );
232         m_menuView->Check( ID_M_VIEW_RADIUS, false );
233         m_menuView->Check( ID_M_VIEW_THRUSTERS, false );
234
235         m_menuView->Enable( ID_M_VIEW_TEXTURING, false );
236         m_menuView->Enable( ID_M_VIEW_SMOOTHING, false );
237
238         m_menuView->Check( ID_M_VIEW_TEXTURING, true );
239         m_menuView->Check( ID_M_VIEW_SMOOTHING, true );
240
241         m_menuView->Enable( ID_M_VIEW_SHIELDS, false );
242         m_menuView->Enable( ID_M_VIEW_INVISIBLE, false );
243         m_menuView->Enable( ID_M_VIEW_BAYPATHS, false );
244         m_menuView->Enable( ID_M_VIEW_AUTOCENTER, false );
245
246         m_menuView->Check( ID_M_VIEW_SHIELDS, false );
247         m_menuView->Check( ID_M_VIEW_INVISIBLE, false );
248         m_menuView->Check( ID_M_VIEW_BAYPATHS, false );
249         m_menuView->Check( ID_M_VIEW_AUTOCENTER, false );
250 }
251
252 void PofViewFrame::SetTools()
253 {
254         polymodel *pm = model_get(m_model_num);
255
256         if (pm->num_debris_objects > 0) {
257                 m_toolBar1->EnableTool( ID_M_TOOLDEBRIS, true );
258         }
259
260         switch (pm->n_detail_levels) {
261                 case 6:
262                         m_toolBar1->EnableTool( ID_M_TOOLDETAIL6, true );
263                 case 5:
264                         m_toolBar1->EnableTool( ID_M_TOOLDETAIL5, true );
265                 case 4:
266                         m_toolBar1->EnableTool( ID_M_TOOLDETAIL4, true );
267                 case 3:
268                         m_toolBar1->EnableTool( ID_M_TOOLDETAIL3, true );
269                 case 2:
270                         m_toolBar1->EnableTool( ID_M_TOOLDETAIL2, true );
271                 case 1:
272                         m_toolBar1->EnableTool( ID_M_TOOLDETAIL1, true );
273                         break;
274
275                 default:
276                         break;
277         }
278
279         if (pm->n_detail_levels >= 1) {
280                 m_toolBar1->ToggleTool( ID_M_TOOLDETAIL1, true );
281         }
282
283         m_toolBar1->EnableTool( ID_M_TOOLSHOWTREE, true );
284         m_toolBar1->EnableTool( ID_M_TOOLSHOWDAMAGED, true );
285
286         m_toolBar1->EnableTool( ID_M_TOOLTOGGLELIGHTS, true );
287
288         m_menuFile->Enable( wxID_CLOSE, true );
289
290         m_menuView->Enable( ID_M_VIEW_OUTLINE, true );
291         m_menuView->Enable( ID_M_VIEW_LIGHTING, true );
292         m_menuView->Enable( ID_M_VIEW_PIVTOS, true );
293         m_menuView->Enable( ID_M_VIEW_PATHS, true );
294         m_menuView->Enable( ID_M_VIEW_RADIUS, true );
295         m_menuView->Enable( ID_M_VIEW_THRUSTERS, true );
296
297         m_menuView->Enable( ID_M_VIEW_TEXTURING, true );
298         m_menuView->Enable( ID_M_VIEW_SMOOTHING, true );
299
300         m_menuView->Enable( ID_M_VIEW_SHIELDS, true );
301         m_menuView->Enable( ID_M_VIEW_INVISIBLE, true );
302         m_menuView->Enable( ID_M_VIEW_BAYPATHS, true );
303         m_menuView->Enable( ID_M_VIEW_AUTOCENTER, true );
304 }
305
306 void PofViewFrame::PofviewInit()
307 {
308         int w, h;
309
310         if (pofview_initted) {
311                 return;
312         }
313
314 #ifndef NDEBUG
315         outwnd_init();
316 #endif
317
318         timer_init();
319
320         cfile_init();
321
322 //      palette_load_table( "gamepalette1-01" );
323
324         key_init();
325         mouse_init();
326
327         m_canvas->GetClientSize(&w, &h);
328
329         gr_init();
330         gr_set_viewport(w, h);
331         gr_set_gamma(2.0f);
332
333         gr_init_font( "font01.vf" );
334
335         model_init();
336
337         pofview_initted = true;
338 }
339
340 void PofViewFrame::OnFileOpen( wxCommandEvent& event )
341 {
342         wxFileDialog openFileDialog(this, _("Open POF File"), wxEmptyString,
343                                                                 wxEmptyString, _("POF Files (*.pof)|*.pof"),
344                                                                 wxFD_OPEN|wxFD_FILE_MUST_EXIST);
345
346         if (openFileDialog.ShowModal() == wxID_OK) {
347                 // close existing model and reset, if anything is open already
348                 if (m_canvas) {
349                         m_canvas->Destroy();
350                         m_canvas = NULL;
351
352                         SetTitle("PofView");
353
354                         model_free_all();
355                         m_model_num = -1;
356
357                         SetToolDefaults();
358                 }
359
360                 // now setup for new model
361                 m_canvas = new PofViewCanvas(this, wxID_ANY, wxDefaultPosition, this->GetClientSize(), wxSUNKEN_BORDER);
362
363                 m_canvas->Show();
364
365                 // reuse the GL context so that we don't have to re-init the graphics
366                 // code between model loads
367                 if ( !m_glContext ) {
368                         m_glContext = new wxGLContext(m_canvas);
369                 }
370
371                 m_canvas->SetCurrent(*m_glContext);
372
373                 PofviewInit();
374
375                 m_model_num = model_load(openFileDialog.GetPath().ToAscii(), 0, NULL);
376                 m_current_detail_level = 1;
377
378                 if (m_model_num < 0) {
379                         m_canvas->Destroy();
380                         m_canvas = NULL;
381
382                         wxString failmsg;
383                         failmsg.Printf("Failed to open: '%s'",openFileDialog.GetPath());
384
385                         wxMessageDialog failDialog(this, failmsg, _("ERROR"), wxOK|wxCENTRE|wxICON_ERROR);
386                         failDialog.ShowModal();
387                 } else {
388                         SetDetailLevel(m_current_detail_level);
389                         SetTools();
390
391                         m_file_name = wxFileName(openFileDialog.GetPath()).GetName();
392
393                         SetTitle( wxString::Format("%s - PofView", m_file_name) );
394                 }
395         }
396 }
397
398 void PofViewFrame::OnFileClose( wxCommandEvent& event )
399 {
400         m_canvas->Destroy();
401         m_canvas = NULL;
402
403         SetTitle("PofView");
404
405         model_free_all();
406         m_model_num = -1;
407
408         SetToolDefaults();
409 }
410
411 void PofViewFrame::OnExit(wxCommandEvent& WXUNUSED(event) )
412 {
413         model_free_all();
414         m_model_num = -1;
415
416         Close(true);
417 }
418
419 void PofViewFrame::OnViewToolbar( wxCommandEvent& event )
420 {
421         bool show_it = event.IsChecked();
422
423         m_toolBar1->Show(show_it);
424 }
425
426 void PofViewFrame::OnViewStatusBar( wxCommandEvent& event )
427 {
428         bool show_it = event.IsChecked();
429
430         m_statusBar1->Show(show_it);
431 }
432
433 void PofViewFrame::OnHelpAbout( wxCommandEvent& WXUNUSED(event) )
434 {
435         AboutBox about(this);
436
437         in_dialog = true;
438
439         about.ShowModal();
440
441         in_dialog = false;
442 }
443
444 void PofViewFrame::OnSetDetail( wxCommandEvent& event )
445 {
446         int detail_lvl = event.GetId() - ID_M_TOOLDEBRIS;
447
448         polymodel *pm = model_get(m_model_num);
449
450         if (pm == NULL) {
451                 return;
452         }
453
454         if (detail_lvl > pm->n_detail_levels) {
455                 Int3();
456                 return;
457         }
458
459         m_current_detail_level = detail_lvl;
460
461         for (int i = ID_M_TOOLDEBRIS; i <= ID_M_TOOLDETAIL6; i++) {
462                 bool bval = false;
463
464                 if ( i == event.GetId() ) {
465                         bval = true;
466                 }
467
468                 m_toolBar1->ToggleTool(i, bval);
469         }
470
471         // update model
472 //      m_canvas->Render();
473 }
474
475 void PofViewFrame::OnShowTree( wxCommandEvent& WXUNUSED(event) )
476 {
477         SubobjectsDialog tree(this);
478
479         tree.ParseModel();
480
481         in_dialog = true;
482
483         tree.ShowModal();
484
485         in_dialog = false;
486 }
487
488 void PofViewFrame::SetDetailLevel(int detail_lvl)
489 {
490         if (m_model_num < 0) {
491                 return;
492         }
493
494         if (detail_lvl < 0) {
495                 return;
496         }
497
498         if (detail_lvl == m_current_detail_level) {
499                 return;
500         }
501
502         polymodel *pm = model_get(m_model_num);
503
504         if (detail_lvl > pm->n_detail_levels) {
505                 return;
506         }
507
508         m_current_detail_level = detail_lvl;
509
510         for (int i = ID_M_TOOLDEBRIS; i <= ID_M_TOOLDETAIL6; i++) {
511                 bool bval = false;
512
513                 if ( i == (ID_M_TOOLDEBRIS + m_current_detail_level) ) {
514                         bval = true;
515                 }
516
517                 m_toolBar1->ToggleTool(i, bval);
518         }
519 }