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