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