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