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