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