]> icculus.org git repositories - taylor/freespace2.git/blob - src/launcher/launcher.cpp
resolve various FS1 build issues
[taylor/freespace2.git] / src / launcher / launcher.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 #include "launcher.h"
10 #include "launchersetup.h"
11
12 #include "wx/filename.h"
13 #include "wx/stdpaths.h"
14
15 #include "pstypes.h"
16 #include "osregistry.h"
17 #include "cfile.h"
18
19 #ifndef MAKE_FS1
20 #include "res/fs2_background.xpm"
21 #include "res/fs2_btn_help.xpm"
22 #include "res/fs2_btn_help-hover.xpm"
23 #include "res/fs2_btn_help-click.xpm"
24 #include "res/fs2_btn_play.xpm"
25 #include "res/fs2_btn_play-hover.xpm"
26 #include "res/fs2_btn_play-click.xpm"
27 #include "res/fs2_btn_pxo.xpm"
28 #include "res/fs2_btn_pxo-hover.xpm"
29 #include "res/fs2_btn_pxo-click.xpm"
30 #include "res/fs2_btn_quit.xpm"
31 #include "res/fs2_btn_quit-hover.xpm"
32 #include "res/fs2_btn_quit-click.xpm"
33 #include "res/fs2_btn_readme.xpm"
34 #include "res/fs2_btn_readme-hover.xpm"
35 #include "res/fs2_btn_readme-click.xpm"
36 #include "res/fs2_btn_setup.xpm"
37 #include "res/fs2_btn_setup-hover.xpm"
38 #include "res/fs2_btn_setup-click.xpm"
39 #include "res/fs2_btn_uninstall.xpm"
40 #include "res/fs2_btn_uninstall-hover.xpm"
41 #include "res/fs2_btn_uninstall-click.xpm"
42 #include "res/fs2_btn_update.xpm"
43 #include "res/fs2_btn_update-hover.xpm"
44 #include "res/fs2_btn_update-click.xpm"
45 #include "res/fs2_btn_volition.xpm"
46 #include "res/fs2_btn_volition-hover.xpm"
47 #include "res/fs2_btn_volition-click.xpm"
48 #include "res/fs2_help_txt.h"
49 #include "res/fs2_snd_hover_wav.h"
50 #include "res/fs2_snd_click_wav.h"
51 #else
52 #include "res/freespace_img.xpm"
53 #include "res/volition_img.xpm"
54 #endif
55
56
57
58 class LauncherApp: public wxApp
59 {
60         public:
61                 virtual bool OnInit();
62 };
63
64
65 IMPLEMENT_APP(LauncherApp)
66
67 bool LauncherApp::OnInit()
68 {
69 #ifdef PLAT_UNIX
70         // make sure we create files with user access only
71         umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
72 #endif
73
74         Launcher *frame = new Launcher(NULL);
75
76         frame->Show();
77         SetTopWindow(frame);
78
79         frame->JumpToSetup();
80
81         return true;
82 }
83
84 bool wxBackgroundBitmap::ProcessEvent(wxEvent &Event)
85 {
86         if (Event.GetEventType() == wxEVT_ERASE_BACKGROUND) {
87                 wxEraseEvent &EraseEvent = dynamic_cast<wxEraseEvent &>(Event);
88                 wxDC *DC = EraseEvent.GetDC();
89                 DC->DrawBitmap(Bitmap, 0, 0, false);
90
91                 return true;
92         } else {
93                 return Inherited::ProcessEvent(Event);
94         }
95 }
96
97
98 wxBEGIN_EVENT_TABLE(wxLauncherButton, wxStaticBitmap)
99         EVT_LEFT_DOWN(wxLauncherButton::onMouseDown)
100         EVT_LEFT_UP(wxLauncherButton::onMouseUp)
101         EVT_MOTION(wxLauncherButton::onMouseEnter)
102 wxEND_EVENT_TABLE()
103
104
105 wxLauncherButton::wxLauncherButton(wxWindow *parent, wxWindowID id, const wxBitmap& label, const wxPoint& pos, const wxSize& size)
106 {
107         this->Create(parent, id, label, pos, size);
108
109         parent->Connect(wxEVT_MOTION, wxMouseEventHandler(wxLauncherButton::onMouseLeave), NULL, this);
110
111         m_bitmap = label;
112
113         m_in_hover = false;
114 }
115
116 wxLauncherButton::~wxLauncherButton()
117 {
118 }
119
120 void wxLauncherButton::onMouseEnter(wxMouseEvent& event)
121 {
122         if ( !m_in_hover ) {
123                 this->SetBitmap(m_bitmap_hover);
124
125                 ((Launcher*)GetGrandParent())->SndPlayHover();
126
127                 m_in_hover = true;
128
129                 // hack to toggle off certain buttons that don't get the onMouseLeave
130                 // call due to placement/overlap
131                 {
132                         wxMouseEvent mv;
133
134                         const wxWindowList wl = GetParent()->GetChildren();
135
136                         wxWindowList::compatibility_iterator node = wl.GetFirst();
137
138                         while (node) {
139                                 wxLauncherButton *cur = (wxLauncherButton*)node->GetData();
140
141                                 if ( cur->GetId() != event.GetId() ) {
142                                         cur->onMouseLeave(mv);
143                                 }
144
145                                 node = node->GetNext();
146                         }
147                 }
148         }
149
150         event.Skip();
151 }
152
153 void wxLauncherButton::onMouseLeave(wxMouseEvent& event)
154 {
155         if (m_in_hover) {
156                 this->SetBitmap(m_bitmap);
157
158                 m_in_hover = false;
159         }
160
161         event.Skip();
162 }
163
164 void wxLauncherButton::onMouseDown(wxMouseEvent& event)
165 {
166         this->SetBitmap(m_bitmap_pressed);
167
168         ((Launcher*)GetGrandParent())->SndPlayPressed();
169
170         event.Skip();
171 }
172
173 void wxLauncherButton::onMouseUp(wxMouseEvent& event)
174 {
175         this->SetBitmap(m_bitmap_hover);
176
177         wxCommandEvent ev(wxEVT_COMMAND_BUTTON_CLICKED, event.GetId());
178         GetGrandParent()->GetEventHandler()->ProcessEvent(ev);
179
180         event.Skip();
181 }
182
183
184 wxBEGIN_EVENT_TABLE(Launcher, wxDialog)
185         EVT_CLOSE(Launcher::OnClose)
186         EVT_BUTTON(ID_B_PLAY, Launcher::OnPlay)
187         EVT_BUTTON(ID_B_SETUP, Launcher::OnSetup)
188         EVT_BUTTON(ID_B_README, Launcher::OnReadme)
189         EVT_BUTTON(ID_B_UPDATE, Launcher::OnUpdate)
190         EVT_BUTTON(ID_B_HELP, Launcher::OnHelp)
191         EVT_BUTTON(ID_B_UNINSTALL, Launcher::OnUninstall)
192         EVT_BUTTON(ID_B_VOLITION, Launcher::OnVolition)
193         EVT_BUTTON(ID_B_PXO, Launcher::OnPXO)
194         EVT_BUTTON(ID_B_QUIT, Launcher::OnQuit)
195 wxEND_EVENT_TABLE()
196
197
198 Launcher::Launcher( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style )
199         : wxDialog( parent, id, title, pos, size, style )
200 {
201         this->SetBackgroundColour( wxColour( 0, 0, 0 ) );
202
203         use_sound = false;
204
205 #ifndef MAKE_FS1
206         this->SetClientSize(375, 440);
207         this->SetTitle( wxT("FreeSpace 2 Launcher") );
208
209         init_sound();
210
211
212         p_background = new wxBackgroundBitmap(fs2_background_xpm);
213
214         m_panel = new wxPanel(this);
215         m_panel->PushEventHandler(p_background);
216
217
218         m_btn_Play = new wxLauncherButton( m_panel, ID_B_PLAY, wxBitmap(fs2_btn_play_xpm), wxPoint(45, 102), wxSize(131, 58) );
219         m_btn_Play->SetBitmapHover( wxBitmap(fs2_btn_play_hover_xpm) );
220         m_btn_Play->SetBitmapPressed( wxBitmap(fs2_btn_play_click_xpm) );
221
222         m_btn_Setup = new wxLauncherButton( m_panel, ID_B_SETUP, wxBitmap(fs2_btn_setup_xpm), wxPoint(199, 102), wxSize(131, 58) );
223         m_btn_Setup->SetBitmapHover( wxBitmap(fs2_btn_setup_hover_xpm) );
224         m_btn_Setup->SetBitmapPressed( wxBitmap(fs2_btn_setup_click_xpm) );
225
226         m_btn_Readme = new wxLauncherButton( m_panel, ID_B_README, wxBitmap(fs2_btn_readme_xpm), wxPoint(45, 175), wxSize(131, 58) );
227         m_btn_Readme->SetBitmapHover( wxBitmap(fs2_btn_readme_hover_xpm) );
228         m_btn_Readme->SetBitmapPressed( wxBitmap(fs2_btn_readme_click_xpm) );
229
230         m_btn_Update = new wxLauncherButton( m_panel, ID_B_UPDATE, wxBitmap(fs2_btn_update_xpm), wxPoint(199, 175), wxSize(131, 58) );
231         m_btn_Update->SetBitmapHover( wxBitmap(fs2_btn_update_hover_xpm) );
232         m_btn_Update->SetBitmapPressed( wxBitmap(fs2_btn_update_click_xpm) );
233
234         m_btn_Help = new wxLauncherButton( m_panel, ID_B_HELP, wxBitmap(fs2_btn_help_xpm), wxPoint(45, 247), wxSize(131, 58) );
235         m_btn_Help->SetBitmapHover( wxBitmap(fs2_btn_help_hover_xpm) );
236         m_btn_Help->SetBitmapPressed( wxBitmap(fs2_btn_help_click_xpm) );
237
238         m_btn_Uninstall = new wxLauncherButton( m_panel, ID_B_UNINSTALL, wxBitmap(fs2_btn_uninstall_xpm), wxPoint(199, 247), wxSize(131, 58) );
239         m_btn_Uninstall->SetBitmapHover( wxBitmap(fs2_btn_uninstall_hover_xpm) );
240         m_btn_Uninstall->SetBitmapPressed( wxBitmap(fs2_btn_uninstall_click_xpm) );
241
242         m_btn_Volition = new wxLauncherButton( m_panel, ID_B_VOLITION, wxBitmap(fs2_btn_volition_xpm), wxPoint(15, 304), wxSize(90, 108) );
243         m_btn_Volition->SetBitmapHover( wxBitmap(fs2_btn_volition_hover_xpm) );
244         m_btn_Volition->SetBitmapPressed( wxBitmap(fs2_btn_volition_click_xpm) );
245
246         m_btn_PXO = new wxLauncherButton( m_panel, ID_B_PXO, wxBitmap(fs2_btn_pxo_xpm), wxPoint(249, 305), wxSize(114, 113) );
247         m_btn_PXO->SetBitmapHover( wxBitmap(fs2_btn_pxo_hover_xpm) );
248         m_btn_PXO->SetBitmapPressed( wxBitmap(fs2_btn_pxo_click_xpm) );
249
250         m_btn_Quit = new wxLauncherButton( m_panel, ID_B_QUIT, wxBitmap(fs2_btn_quit_xpm), wxPoint(116, 339), wxSize(131, 58) );
251         m_btn_Quit->SetBitmapHover( wxBitmap(fs2_btn_quit_hover_xpm) );
252         m_btn_Quit->SetBitmapPressed( wxBitmap(fs2_btn_quit_click_xpm) );
253 #else
254         this->SetSizeHints( wxDefaultSize, wxDefaultSize );
255         this->SetTitle( wxT("FreeSpace Launcher") );
256
257         wxBoxSizer* bSizer3;
258         bSizer3 = new wxBoxSizer( wxVERTICAL );
259
260         wxStaticBitmap *m_bitmap1 = new wxStaticBitmap( this, wxID_ANY, wxBitmap( freespace_img_xpm ), wxDefaultPosition, wxDefaultSize, 0 );
261         bSizer3->Add( m_bitmap1, 0, wxALIGN_LEFT|wxALIGN_TOP|wxALL, 5 );
262
263         wxFlexGridSizer* fgSizer3;
264         fgSizer3 = new wxFlexGridSizer( 0, 2, 0, 0 );
265         fgSizer3->SetFlexibleDirection( wxBOTH );
266         fgSizer3->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
267
268         wxStaticBitmap *m_bitmap2 = new wxStaticBitmap( this, wxID_ANY, wxBitmap( volition_img_xpm ), wxDefaultPosition, wxDefaultSize, 0 );
269         fgSizer3->Add( m_bitmap2, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
270
271         wxBoxSizer* bSizer5;
272         bSizer5 = new wxBoxSizer( wxVERTICAL );
273
274         m_btn_Play = new wxButton( this, ID_B_PLAY, wxT("Play FreeSpace"), wxDefaultPosition, wxDefaultSize, 0 );
275         m_btn_Play->SetDefault();
276         bSizer5->Add( m_btn_Play, 0, wxALL|wxEXPAND, 5 );
277
278         m_btn_Setup = new wxButton( this, ID_B_SETUP, wxT("Setup"), wxDefaultPosition, wxDefaultSize, 0 );
279         bSizer5->Add( m_btn_Setup, 0, wxALL|wxEXPAND, 5 );
280
281         m_btn_Readme = new wxButton( this, ID_B_README, wxT("View README"), wxDefaultPosition, wxDefaultSize, 0 );
282         bSizer5->Add( m_btn_Readme, 0, wxALL|wxEXPAND, 5 );
283
284         m_btn_Update = new wxButton( this, ID_B_UPDATE, wxT("Update FreeSpace"), wxDefaultPosition, wxDefaultSize, 0 );
285         bSizer5->Add( m_btn_Update, 0, wxALL|wxEXPAND, 5 );
286
287         m_btn_Volition = new wxButton( this, ID_B_VOLITION, wxT("FreeSpace Webpage"), wxDefaultPosition, wxDefaultSize, 0 );
288         bSizer5->Add( m_btn_Volition, 0, wxALL|wxEXPAND, 5 );
289
290         m_btn_Uninstall = new wxButton( this, ID_B_UNINSTALL, wxT("Uninstall"), wxDefaultPosition, wxDefaultSize, 0 );
291         bSizer5->Add( m_btn_Uninstall, 0, wxALL|wxEXPAND, 5 );
292
293         m_btn_Quit = new wxButton( this, ID_B_QUIT, wxT("Quit"), wxDefaultPosition, wxDefaultSize, 0 );
294         bSizer5->Add( m_btn_Quit, 0, wxALL|wxEXPAND, 5 );
295
296         fgSizer3->Add( bSizer5, 1, wxALIGN_CENTER|wxALL, 10 );
297
298         bSizer3->Add( fgSizer3, 1, wxALIGN_BOTTOM|wxALIGN_RIGHT|wxEXPAND, 5 );
299
300         this->SetSizer( bSizer3 );
301         this->Layout();
302         bSizer3->Fit( this );
303 #endif
304
305
306         this->Centre( wxBOTH );
307 }
308
309 Launcher::~Launcher()
310 {
311         close_sound();
312 }
313
314 void Launcher::OnClose( wxCloseEvent& WXUNUSED(event) )
315 {
316 #ifndef MAKE_FS1
317         m_panel->RemoveEventHandler(p_background);
318         delete p_background;
319 #endif
320
321         Destroy();
322 }
323
324 void Launcher::OnPlay( wxCommandEvent& WXUNUSED(event) )
325 {
326         wxString epath = wxFileName(wxStandardPaths::Get().GetExecutablePath()).GetPath(true);
327
328 #ifndef MAKE_FS1
329         epath.Append( wxT("freespace2") );
330 #else
331         epath.Append( wxT("freespace") );
332 #endif
333
334 #ifdef FS2_DEMO
335         epath.Append( wxT("_demo") );
336 #endif
337
338 #ifdef _WIN32
339         epath.Append( wxT(".exe") );
340 #endif
341
342         wxExecute(epath, wxEXEC_ASYNC | wxEXEC_MAKE_GROUP_LEADER | wxEXEC_HIDE_CONSOLE);
343
344         this->Close();
345 }
346
347 void Launcher::OnSetup( wxCommandEvent& WXUNUSED(event) )
348 {
349         LauncherSetup setup(this);
350
351         setup.ShowModal();
352 }
353
354 void Launcher::OnReadme( wxCommandEvent& WXUNUSED(event) )
355 {
356         wxLaunchDefaultApplication("README.txt");
357 }
358
359 void Launcher::OnUpdate( wxCommandEvent& WXUNUSED(event) )
360 {
361         wxMessageBox( wxT("Not implemented") );
362 }
363
364 void Launcher::OnHelp( wxCommandEvent& WXUNUSED(event) )
365 {
366 #ifndef MAKE_FS1
367         wxDialog *help = new wxDialog(this, wxID_ANY, wxT("Launcher Help"), wxDefaultPosition, wxDefaultSize, wxCAPTION|wxSYSTEM_MENU);
368
369         wxBoxSizer* bSizer;
370         bSizer = new wxBoxSizer( wxVERTICAL );
371
372         // stupid
373         wxSize txtsize = help->GetTextExtent( wxT("  This opens a Help document containing information about the LauncherWW") );
374         txtsize.SetHeight(420);
375
376         wxTextCtrl *m_help_txt = new wxTextCtrl( help, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_DONTWRAP|wxTE_MULTILINE|wxTE_READONLY );
377         m_help_txt->SetMinSize(txtsize);
378         m_help_txt->AppendText(fs2_help_txt);
379         m_help_txt->SetInsertionPoint(0);
380         bSizer->Add( m_help_txt, 0, wxALL|wxEXPAND, 5 );
381
382         wxButton *m_b_Ok = new wxButton( help, wxID_OK, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
383         bSizer->Add( m_b_Ok, 0, wxALIGN_BOTTOM|wxALIGN_RIGHT|wxALL, 5 );
384
385         help->SetSizer( bSizer );
386         help->Layout();
387         bSizer->Fit(help);
388
389         help->Centre( wxBOTH );
390
391         help->ShowModal();
392
393         help->Destroy();
394 #endif
395 }
396
397 void Launcher::OnUninstall( wxCommandEvent& WXUNUSED(event) )
398 {
399         wxMessageBox( wxT("Not implemented") );
400 }
401
402 void Launcher::OnVolition( wxCommandEvent& WXUNUSED(event) )
403 {
404         wxLaunchDefaultBrowser( wxT("http://www.volition-inc.com") );
405 }
406
407 void Launcher::OnPXO( wxCommandEvent& WXUNUSED(event) )
408 {
409         wxLaunchDefaultBrowser( wxT("http://www.pxo.net") );
410 }
411
412 void Launcher::OnQuit( wxCommandEvent& WXUNUSED(event) )
413 {
414         this->Close();
415 }
416
417 void Launcher::JumpToSetup()
418 {
419         if ( !os_config_read_uint(NULL, "StraightToSetup", 1) ) {
420                 return;
421         }
422
423         // FS1 doesn't do a setup jump so just go with what the user sets up
424         // and/or what the game binary will set
425
426 #ifndef MAKE_FS1
427         wxString title( wxT("Welcome to FreeSpace 2!") );
428
429         wxString message( wxT("Since this is your first time running FreeSapce2, ")
430                                           wxT("you will now be automatically taken to the Setup ")
431                                           wxT("window.") );
432
433         wxString ext_message( wxT("NOTE TO USER:\n")
434                                                   wxT("It is important that you view each section of ")
435                                                   wxT("the Setup window and configure it to your ")
436                                                   wxT("liking. Press the Help button if you have ")
437                                                   wxT("questions about a particular section. Once you ")
438                                                   wxT("are satisfied with your settings, select the OK ")
439                                                   wxT("button at the bottom of the Setup window to ")
440                                                   wxT("save them.") );
441
442         wxMessageDialog prompt(this, message, title, wxOK | wxICON_INFORMATION);
443         prompt.SetExtendedMessage(ext_message);
444
445         prompt.ShowModal();
446
447         // now jump to setup dialog
448         LauncherSetup setup(this);
449
450         setup.ShowModal();
451 #endif
452 }
453
454 void Launcher::SndPlayHover()
455 {
456         if (use_sound) {
457                 alSourcePlay(m_snd_hover_source_id);
458         }
459 }
460
461 void Launcher::SndPlayPressed()
462 {
463         if (use_sound) {
464                 alSourcePlay(m_snd_click_source_id);
465         }
466 }
467
468 void Launcher::SndEnable(bool enabled)
469 {
470         if (enabled) {
471                 init_sound();
472         } else {
473                 close_sound();
474         }
475 }
476
477 void Launcher::init_sound()
478 {
479 #ifndef MAKE_FS1
480         if (use_sound) {
481                 return;
482         }
483
484         if ( os_config_read_uint("Audio", "LauncherSoundEnabled", 1) == 0 ) {
485                 return;
486         }
487
488         al_device = alcOpenDevice(NULL);
489
490         if (al_device == NULL) {
491                 return;
492         }
493
494         al_context = alcCreateContext(al_device, NULL);
495
496         if (al_context == NULL) {
497                 alcCloseDevice(al_device);
498                 return;
499         }
500
501         alcMakeContextCurrent(al_context);
502
503         // 'hover' sound
504         alGenBuffers(1, &m_snd_hover_buf_id);
505         alBufferData(m_snd_hover_buf_id, AL_FORMAT_MONO8, fs2_snd_hover_wav, sizeof(fs2_snd_hover_wav), 22050);
506
507         alGenSources(1, &m_snd_hover_source_id);
508         alSourcef(m_snd_hover_source_id, AL_GAIN, 1.0f);
509         alSourcei(m_snd_hover_source_id, AL_BUFFER, m_snd_hover_buf_id);
510
511         // 'click' sound
512         alGenBuffers(1, &m_snd_click_buf_id);
513         alBufferData(m_snd_click_buf_id, AL_FORMAT_MONO8, fs2_snd_click_wav, sizeof(fs2_snd_click_wav), 22050);
514
515         alGenSources(1, &m_snd_click_source_id);
516         alSourcef(m_snd_click_source_id, AL_GAIN, 1.0f);
517         alSourcei(m_snd_click_source_id, AL_BUFFER, m_snd_click_buf_id);
518
519         use_sound = true;
520 #endif
521 }
522
523 void Launcher::close_sound()
524 {
525         if ( !use_sound ) {
526                 return;
527         }
528
529         alSourceStop(m_snd_click_source_id);
530
531         alSourcei(m_snd_click_source_id, AL_BUFFER, 0);
532         alDeleteSources(1, &m_snd_click_source_id);
533         alDeleteBuffers(1, &m_snd_click_buf_id);
534
535         alSourceStop(m_snd_hover_source_id);
536
537         alSourcei(m_snd_hover_source_id, AL_BUFFER, 0);
538         alDeleteSources(1, &m_snd_hover_source_id);
539         alDeleteBuffers(1, &m_snd_hover_buf_id);
540
541         alcMakeContextCurrent(NULL);
542         alcDestroyContext(al_context);
543         alcCloseDevice(al_device);
544
545         use_sound = false;
546 }