]> icculus.org git repositories - taylor/freespace2.git/blob - src/launcher/launcher.cpp
set proper launcher title for demo builds
[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 #ifdef FS2_DEMO
208         this->SetTitle( wxT("FreeSpace 2 Demo Launcher") );
209 #else
210         this->SetTitle( wxT("FreeSpace 2 Launcher") );
211 #endif
212
213         init_sound();
214
215
216         p_background = new wxBackgroundBitmap(fs2_background_xpm);
217
218         m_panel = new wxPanel(this);
219         m_panel->PushEventHandler(p_background);
220
221
222         m_btn_Play = new wxLauncherButton( m_panel, ID_B_PLAY, wxBitmap(fs2_btn_play_xpm), wxPoint(45, 102), wxSize(131, 58) );
223         m_btn_Play->SetBitmapHover( wxBitmap(fs2_btn_play_hover_xpm) );
224         m_btn_Play->SetBitmapPressed( wxBitmap(fs2_btn_play_click_xpm) );
225
226         m_btn_Setup = new wxLauncherButton( m_panel, ID_B_SETUP, wxBitmap(fs2_btn_setup_xpm), wxPoint(199, 102), wxSize(131, 58) );
227         m_btn_Setup->SetBitmapHover( wxBitmap(fs2_btn_setup_hover_xpm) );
228         m_btn_Setup->SetBitmapPressed( wxBitmap(fs2_btn_setup_click_xpm) );
229
230         m_btn_Readme = new wxLauncherButton( m_panel, ID_B_README, wxBitmap(fs2_btn_readme_xpm), wxPoint(45, 175), wxSize(131, 58) );
231         m_btn_Readme->SetBitmapHover( wxBitmap(fs2_btn_readme_hover_xpm) );
232         m_btn_Readme->SetBitmapPressed( wxBitmap(fs2_btn_readme_click_xpm) );
233
234         m_btn_Update = new wxLauncherButton( m_panel, ID_B_UPDATE, wxBitmap(fs2_btn_update_xpm), wxPoint(199, 175), wxSize(131, 58) );
235         m_btn_Update->SetBitmapHover( wxBitmap(fs2_btn_update_hover_xpm) );
236         m_btn_Update->SetBitmapPressed( wxBitmap(fs2_btn_update_click_xpm) );
237
238         m_btn_Help = new wxLauncherButton( m_panel, ID_B_HELP, wxBitmap(fs2_btn_help_xpm), wxPoint(45, 247), wxSize(131, 58) );
239         m_btn_Help->SetBitmapHover( wxBitmap(fs2_btn_help_hover_xpm) );
240         m_btn_Help->SetBitmapPressed( wxBitmap(fs2_btn_help_click_xpm) );
241
242         m_btn_Uninstall = new wxLauncherButton( m_panel, ID_B_UNINSTALL, wxBitmap(fs2_btn_uninstall_xpm), wxPoint(199, 247), wxSize(131, 58) );
243         m_btn_Uninstall->SetBitmapHover( wxBitmap(fs2_btn_uninstall_hover_xpm) );
244         m_btn_Uninstall->SetBitmapPressed( wxBitmap(fs2_btn_uninstall_click_xpm) );
245
246         m_btn_Volition = new wxLauncherButton( m_panel, ID_B_VOLITION, wxBitmap(fs2_btn_volition_xpm), wxPoint(15, 304), wxSize(90, 108) );
247         m_btn_Volition->SetBitmapHover( wxBitmap(fs2_btn_volition_hover_xpm) );
248         m_btn_Volition->SetBitmapPressed( wxBitmap(fs2_btn_volition_click_xpm) );
249
250         m_btn_PXO = new wxLauncherButton( m_panel, ID_B_PXO, wxBitmap(fs2_btn_pxo_xpm), wxPoint(249, 305), wxSize(114, 113) );
251         m_btn_PXO->SetBitmapHover( wxBitmap(fs2_btn_pxo_hover_xpm) );
252         m_btn_PXO->SetBitmapPressed( wxBitmap(fs2_btn_pxo_click_xpm) );
253
254         m_btn_Quit = new wxLauncherButton( m_panel, ID_B_QUIT, wxBitmap(fs2_btn_quit_xpm), wxPoint(116, 339), wxSize(131, 58) );
255         m_btn_Quit->SetBitmapHover( wxBitmap(fs2_btn_quit_hover_xpm) );
256         m_btn_Quit->SetBitmapPressed( wxBitmap(fs2_btn_quit_click_xpm) );
257 #else
258         this->SetSizeHints( wxDefaultSize, wxDefaultSize );
259 #ifdef FS1_DEMO
260         this->SetTitle( wxT("FreeSpace Demo Launcher") );
261 #else
262         this->SetTitle( wxT("FreeSpace Launcher") );
263 #endif
264
265         wxBoxSizer* bSizer3;
266         bSizer3 = new wxBoxSizer( wxVERTICAL );
267
268         wxStaticBitmap *m_bitmap1 = new wxStaticBitmap( this, wxID_ANY, wxBitmap( freespace_img_xpm ), wxDefaultPosition, wxDefaultSize, 0 );
269         bSizer3->Add( m_bitmap1, 0, wxALIGN_LEFT|wxALIGN_TOP|wxALL, 5 );
270
271         wxFlexGridSizer* fgSizer3;
272         fgSizer3 = new wxFlexGridSizer( 0, 2, 0, 0 );
273         fgSizer3->SetFlexibleDirection( wxBOTH );
274         fgSizer3->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
275
276         wxStaticBitmap *m_bitmap2 = new wxStaticBitmap( this, wxID_ANY, wxBitmap( volition_img_xpm ), wxDefaultPosition, wxDefaultSize, 0 );
277         fgSizer3->Add( m_bitmap2, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
278
279         wxBoxSizer* bSizer5;
280         bSizer5 = new wxBoxSizer( wxVERTICAL );
281
282         m_btn_Play = new wxButton( this, ID_B_PLAY, wxT("Play FreeSpace"), wxDefaultPosition, wxDefaultSize, 0 );
283         m_btn_Play->SetDefault();
284         bSizer5->Add( m_btn_Play, 0, wxALL|wxEXPAND, 5 );
285
286         m_btn_Setup = new wxButton( this, ID_B_SETUP, wxT("Setup"), wxDefaultPosition, wxDefaultSize, 0 );
287         bSizer5->Add( m_btn_Setup, 0, wxALL|wxEXPAND, 5 );
288
289         m_btn_Readme = new wxButton( this, ID_B_README, wxT("View README"), wxDefaultPosition, wxDefaultSize, 0 );
290         bSizer5->Add( m_btn_Readme, 0, wxALL|wxEXPAND, 5 );
291
292         m_btn_Update = new wxButton( this, ID_B_UPDATE, wxT("Update FreeSpace"), wxDefaultPosition, wxDefaultSize, 0 );
293         bSizer5->Add( m_btn_Update, 0, wxALL|wxEXPAND, 5 );
294
295         m_btn_Volition = new wxButton( this, ID_B_VOLITION, wxT("FreeSpace Webpage"), wxDefaultPosition, wxDefaultSize, 0 );
296         bSizer5->Add( m_btn_Volition, 0, wxALL|wxEXPAND, 5 );
297
298         m_btn_Uninstall = new wxButton( this, ID_B_UNINSTALL, wxT("Uninstall"), wxDefaultPosition, wxDefaultSize, 0 );
299         bSizer5->Add( m_btn_Uninstall, 0, wxALL|wxEXPAND, 5 );
300
301         m_btn_Quit = new wxButton( this, ID_B_QUIT, wxT("Quit"), wxDefaultPosition, wxDefaultSize, 0 );
302         bSizer5->Add( m_btn_Quit, 0, wxALL|wxEXPAND, 5 );
303
304         fgSizer3->Add( bSizer5, 1, wxALIGN_CENTER|wxALL, 10 );
305
306         bSizer3->Add( fgSizer3, 1, wxALIGN_BOTTOM|wxALIGN_RIGHT|wxEXPAND, 5 );
307
308         this->SetSizer( bSizer3 );
309         this->Layout();
310         bSizer3->Fit( this );
311 #endif
312
313
314         this->Centre( wxBOTH );
315 }
316
317 Launcher::~Launcher()
318 {
319         close_sound();
320 }
321
322 void Launcher::OnClose( wxCloseEvent& WXUNUSED(event) )
323 {
324 #ifndef MAKE_FS1
325         m_panel->RemoveEventHandler(p_background);
326         delete p_background;
327 #endif
328
329         Destroy();
330 }
331
332 void Launcher::OnPlay( wxCommandEvent& WXUNUSED(event) )
333 {
334         wxString epath = wxFileName(wxStandardPaths::Get().GetExecutablePath()).GetPath(true);
335
336         epath.Append( wxT("fs") );
337
338 #ifndef MAKE_FS1
339         epath.Append( wxT("2") );
340 #endif
341
342 #if defined(FS1_DEMO) || defined(FS2_DEMO)
343         epath.Append( wxT("demo") );
344 #endif
345
346 #ifdef _WIN32
347         epath.Append( wxT(".exe") );
348 #endif
349
350         wxExecute(epath, wxEXEC_ASYNC | wxEXEC_MAKE_GROUP_LEADER);
351
352         this->Close();
353 }
354
355 void Launcher::OnSetup( wxCommandEvent& WXUNUSED(event) )
356 {
357         LauncherSetup setup(this);
358
359         setup.ShowModal();
360 }
361
362 void Launcher::OnReadme( wxCommandEvent& WXUNUSED(event) )
363 {
364         wxLaunchDefaultApplication("README.txt");
365 }
366
367 void Launcher::OnUpdate( wxCommandEvent& WXUNUSED(event) )
368 {
369         wxMessageBox( wxT("Not implemented") );
370 }
371
372 void Launcher::OnHelp( wxCommandEvent& WXUNUSED(event) )
373 {
374 #ifndef MAKE_FS1
375         wxDialog *help = new wxDialog(this, wxID_ANY, wxT("Launcher Help"), wxDefaultPosition, wxDefaultSize, wxCAPTION|wxSYSTEM_MENU);
376
377         wxBoxSizer* bSizer;
378         bSizer = new wxBoxSizer( wxVERTICAL );
379
380         // stupid
381         wxSize txtsize = help->GetTextExtent( wxT("  This opens a Help document containing information about the LauncherWWWW") );
382         txtsize.SetHeight(420);
383
384         wxTextCtrl *m_help_txt = new wxTextCtrl( help, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_DONTWRAP|wxTE_MULTILINE|wxTE_READONLY );
385         m_help_txt->SetMinSize(txtsize);
386         m_help_txt->AppendText(fs2_help_txt);
387         m_help_txt->SetInsertionPoint(0);
388         bSizer->Add( m_help_txt, 0, wxALL|wxEXPAND, 5 );
389
390         wxButton *m_b_Ok = new wxButton( help, wxID_OK, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
391         bSizer->Add( m_b_Ok, 0, wxALIGN_RIGHT|wxALL, 5 );
392
393         help->SetSizer( bSizer );
394         help->Layout();
395         bSizer->Fit(help);
396
397         help->Centre( wxBOTH );
398
399         help->ShowModal();
400
401         help->Destroy();
402 #endif
403 }
404
405 void Launcher::OnUninstall( wxCommandEvent& WXUNUSED(event) )
406 {
407         wxMessageBox( wxT("Not implemented") );
408 }
409
410 void Launcher::OnVolition( wxCommandEvent& WXUNUSED(event) )
411 {
412         wxLaunchDefaultBrowser( wxT("http://www.volition-inc.com") );
413 }
414
415 void Launcher::OnPXO( wxCommandEvent& WXUNUSED(event) )
416 {
417         wxLaunchDefaultBrowser( wxT("http://www.pxo.net") );
418 }
419
420 void Launcher::OnQuit( wxCommandEvent& WXUNUSED(event) )
421 {
422         this->Close();
423 }
424
425 void Launcher::JumpToSetup()
426 {
427         if ( !os_config_read_uint(NULL, "StraightToSetup", 1) ) {
428                 return;
429         }
430
431         // FS1 doesn't do a setup jump so just go with what the user sets up
432         // and/or what the game binary will set
433
434 #ifndef MAKE_FS1
435         wxString title( wxT("Welcome to FreeSpace 2!") );
436
437         wxString message( wxT("Since this is your first time running FreeSapce2, ")
438                                           wxT("you will now be automatically taken to the Setup ")
439                                           wxT("window.") );
440
441         wxString ext_message( wxT("NOTE TO USER:\n")
442                                                   wxT("It is important that you view each section of ")
443                                                   wxT("the Setup window and configure it to your ")
444                                                   wxT("liking. Press the Help button if you have ")
445                                                   wxT("questions about a particular section. Once you ")
446                                                   wxT("are satisfied with your settings, select the OK ")
447                                                   wxT("button at the bottom of the Setup window to ")
448                                                   wxT("save them.") );
449
450         wxMessageDialog prompt(this, message, title, wxOK | wxICON_INFORMATION);
451         prompt.SetExtendedMessage(ext_message);
452
453         prompt.ShowModal();
454
455         // now jump to setup dialog
456         LauncherSetup setup(this);
457
458         setup.ShowModal();
459 #endif
460 }
461
462 void Launcher::SndPlayHover()
463 {
464         if (use_sound) {
465                 alSourcePlay(m_snd_hover_source_id);
466         }
467 }
468
469 void Launcher::SndPlayPressed()
470 {
471         if (use_sound) {
472                 alSourcePlay(m_snd_click_source_id);
473         }
474 }
475
476 void Launcher::SndEnable(bool enabled)
477 {
478         if (enabled) {
479                 init_sound();
480         } else {
481                 close_sound();
482         }
483 }
484
485 void Launcher::init_sound()
486 {
487 #ifndef MAKE_FS1
488         if (use_sound) {
489                 return;
490         }
491
492         if ( os_config_read_uint("Audio", "LauncherSoundEnabled", 1) == 0 ) {
493                 return;
494         }
495
496         al_device = alcOpenDevice(NULL);
497
498         if (al_device == NULL) {
499                 return;
500         }
501
502         al_context = alcCreateContext(al_device, NULL);
503
504         if (al_context == NULL) {
505                 alcCloseDevice(al_device);
506                 return;
507         }
508
509         alcMakeContextCurrent(al_context);
510
511         // 'hover' sound
512         alGenBuffers(1, &m_snd_hover_buf_id);
513         alBufferData(m_snd_hover_buf_id, AL_FORMAT_MONO8, fs2_snd_hover_wav, sizeof(fs2_snd_hover_wav), 22050);
514
515         alGenSources(1, &m_snd_hover_source_id);
516         alSourcef(m_snd_hover_source_id, AL_GAIN, 1.0f);
517         alSourcei(m_snd_hover_source_id, AL_BUFFER, m_snd_hover_buf_id);
518
519         // 'click' sound
520         alGenBuffers(1, &m_snd_click_buf_id);
521         alBufferData(m_snd_click_buf_id, AL_FORMAT_MONO8, fs2_snd_click_wav, sizeof(fs2_snd_click_wav), 22050);
522
523         alGenSources(1, &m_snd_click_source_id);
524         alSourcef(m_snd_click_source_id, AL_GAIN, 1.0f);
525         alSourcei(m_snd_click_source_id, AL_BUFFER, m_snd_click_buf_id);
526
527         use_sound = true;
528 #endif
529 }
530
531 void Launcher::close_sound()
532 {
533         if ( !use_sound ) {
534                 return;
535         }
536
537         alSourceStop(m_snd_click_source_id);
538
539         alSourcei(m_snd_click_source_id, AL_BUFFER, 0);
540         alDeleteSources(1, &m_snd_click_source_id);
541         alDeleteBuffers(1, &m_snd_click_buf_id);
542
543         alSourceStop(m_snd_hover_source_id);
544
545         alSourcei(m_snd_hover_source_id, AL_BUFFER, 0);
546         alDeleteSources(1, &m_snd_hover_source_id);
547         alDeleteBuffers(1, &m_snd_hover_buf_id);
548
549         alcMakeContextCurrent(NULL);
550         alcDestroyContext(al_context);
551         alcCloseDevice(al_device);
552
553         use_sound = false;
554 }