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