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