]> icculus.org git repositories - taylor/freespace2.git/blob - src/fred2/bgbitmapdlg.cpp
The Great Newline Fix
[taylor/freespace2.git] / src / fred2 / bgbitmapdlg.cpp
1 /*
2  * $Logfile: /Freespace2/code/Fred2/BgBitmapDlg.cpp $
3  * $Revision$
4  * $Date$
5  * $Author$
6  *
7  * Background space images manager dialog
8  *
9  * $Log$
10  * Revision 1.2  2002/05/07 03:16:43  theoddone33
11  * The Great Newline Fix
12  *
13  * Revision 1.1.1.1  2002/05/03 03:28:08  root
14  * Initial import.
15  *
16  * 
17  * 11    7/02/99 4:30p Dave
18  * Much more sophisticated lightning support.
19  * 
20  * 10    6/08/99 5:42p Dave
21  * Fixed background bitmap division stuff.
22  * 
23  * 9     6/03/99 6:42p Dave
24  * 
25  * 8     6/03/99 6:37p Dave
26  * More TNT fun. Made perspective bitmaps more flexible.
27  * 
28  * 7     5/09/99 6:00p Dave
29  * Lots of cool new effects. E3 build tweaks.
30  * 
31  * 6     4/26/99 8:47p Dave
32  * Made all pof related nebula stuff customizable through Fred.
33  * 
34  * 5     4/07/99 6:21p Dave
35  * Fred and Freespace support for multiple background bitmaps and suns.
36  * Fixed link errors on all subprojects. Moved encrypt_init() to
37  * cfile_init() and lcl_init(), since its safe to call twice.
38  * 
39  * 4     1/25/99 5:03a Dave
40  * First run of stealth, AWACS and TAG missile support. New mission type
41  * :)
42  * 
43  * 3     11/14/98 5:37p Dave
44  * Put in support for full nebulas.
45  * 
46  * 2     10/07/98 6:28p Dave
47  * Initial checkin. Renamed all relevant stuff to be Fred2 instead of
48  * Fred. Globalized mission and campaign file extensions. Removed Silent
49  * Threat specific code.
50  *   
51  * 18    4/13/98 10:25p Hoffoss
52  * Added a flag for subspace missions, and for aboard the Galatea or
53  * Bastion.
54  * 
55  * 17    1/14/98 8:56a John
56  * Removed old nebula palette code that didn't matter what HUD colors were
57  * loaded.
58  * 
59  * 16    12/08/97 4:48p Hoffoss
60  * Moved starfield editor controls to background editor.
61  * 
62  * 15    11/25/97 4:48p Johnson
63  * Fixed bug with nebula selection.
64  * 
65  * 14    11/25/97 11:40a Hoffoss
66  * Added support for nebula placement editing.
67  * 
68  * 13    11/23/97 6:06p Hoffoss
69  * Renamed background bitmap editor to just background editor.
70  * 
71  * 12    11/21/97 2:55p Hoffoss
72  * Added Nebula support to Fred.  Implemented loading and saving nebula
73  * info to/from mission files.
74  * 
75  * 11    6/11/97 3:26p Hoffoss
76  * Added better verification of bitmap filename to BG editor.
77  * 
78  * 10    4/17/97 2:01p Hoffoss
79  * All dialog box window states are saved between sessions now.
80  * 
81  * 9     3/31/97 6:07p Hoffoss
82  * Fixed several errors, including BG editor not graying fields, BG editor
83  * not updating image when changed, Removed obsolete data from Weapon
84  * editor, priority not being saved when missions saved, priority not
85  * editable in initial orders editor.
86  * 
87  * 8     3/27/97 2:24p Hoffoss
88  * Fixed bug in image not updating when new image selected from listbox of
89  * combo box.
90  * 
91  * 7     3/21/97 4:24p Hoffoss
92  * Fixed bug in changing image to an external image file.
93  * 
94  * 6     3/17/97 1:54p Hoffoss
95  * fixed bugs in BG editor, and added delete button functionality.
96  * 
97  * 5     3/12/97 4:33p Hoffoss
98  * added spin controls to orient editor, light intensity level can be
99  * specified in BG editor.
100  * 
101  * 4     2/21/97 5:34p Hoffoss
102  * Added extensive modification detection and fixed a bug in initial
103  * orders editor.
104  * 
105  * 3     2/04/97 3:09p Hoffoss
106  * Background bitmap editor implemented fully.
107  * 
108  * 2     1/30/97 2:24p Hoffoss
109  * Added remaining mission file structures and implemented load/save of
110  * them.
111  *
112  * $NoKeywords: $
113  */
114
115 #include "stdafx.h"
116 #include "fred.h"
117 #include "bgbitmapdlg.h"
118 #include "starfield.h"
119 #include "bmpman.h"
120 #include "fredview.h"
121 #include "freddoc.h"
122 #include "palman.h"
123 #include "nebula.h"
124 #include "neb.h"
125 #include "neblightning.h"
126
127 #ifdef _DEBUG
128 #define new DEBUG_NEW
129 #undef THIS_FILE
130 static char THIS_FILE[] = __FILE__;
131 #endif
132
133 /////////////////////////////////////////////////////////////////////////////
134 // bg_bitmap_dlg dialog
135
136 bg_bitmap_dlg::bg_bitmap_dlg(CWnd* pParent) : CDialog(bg_bitmap_dlg::IDD, pParent)
137 {
138         //{{AFX_DATA_INIT(bg_bitmap_dlg)                
139         m_neb_intensity = _T("");       
140         m_nebula_color = -1;
141         m_nebula_index = -1;
142         m_bank = 0;
143         m_heading = 0;
144         m_pitch = 0;
145         m_subspace = FALSE;
146         m_fullneb = FALSE;
147
148         m_neb2_texture = 0;
149         
150         for(int idx=0; idx<MAX_NEB2_POOFS; idx++){
151                 m_poof[idx] = Neb2_poof_flags & (1<<idx) ? 1 : 0;
152         }
153
154         s_pitch = 0;
155         s_bank = 0;
156         s_heading = 0;
157         s_scale = 1.0f; 
158         s_index = -1;
159
160         b_pitch = 0;
161         b_bank = 0;
162         b_heading = 0;
163         b_scale_x = 1.0f; b_scale_y = 1.0f;
164         b_div_x = 1; b_div_y = 1;
165         b_index = -1;
166         //}}AFX_DATA_INIT       
167 }
168
169 void bg_bitmap_dlg::DoDataExchange(CDataExchange* pDX)
170 {
171         CDialog::DoDataExchange(pDX);
172         //{{AFX_DATA_MAP(bg_bitmap_dlg)                 
173         DDX_CBIndex(pDX, IDC_NEBCOLOR, m_nebula_color);
174         DDX_CBIndex(pDX, IDC_NEBPATTERN, m_nebula_index);
175         DDX_Text(pDX, IDC_BANK, m_bank);
176         DDX_Text(pDX, IDC_HEADING, m_heading);
177         DDX_Text(pDX, IDC_PITCH, m_pitch);
178         DDX_Text(pDX, IDC_NEB2_INTENSITY, m_neb_intensity);
179         DDX_Control(pDX, IDC_SLIDER1, m_slider);
180         DDX_Check(pDX, IDC_SUBSPACE, m_subspace);
181         DDX_Check(pDX, IDC_FULLNEB, m_fullneb);
182
183         DDX_CBIndex(pDX, IDC_NEB2_TEXTURE, m_neb2_texture);
184
185         DDX_Text(pDX, IDC_SUN1, s_name);
186         DDX_Text(pDX, IDC_SUN1_P, s_pitch);
187         DDV_MinMaxInt(pDX, s_pitch, 0, 359);
188         DDX_Text(pDX, IDC_SUN1_B, s_bank);
189         DDV_MinMaxInt(pDX, s_bank, 0, 359);
190         DDX_Text(pDX, IDC_SUN1_H, s_heading);
191         DDV_MinMaxInt(pDX, s_heading, 0, 359);
192         DDX_Text(pDX, IDC_SUN1_SCALE, s_scale);
193         DDV_MinMaxFloat(pDX, s_scale, 0.1f, 50.0f);
194
195         DDX_Text(pDX, IDC_SBITMAP, b_name);
196         DDX_Text(pDX, IDC_SBITMAP_P, b_pitch);
197         DDV_MinMaxInt(pDX, b_pitch, 0, 359);
198         DDX_Text(pDX, IDC_SBITMAP_B, b_bank);
199         DDV_MinMaxInt(pDX, b_bank, 0, 359);
200         DDX_Text(pDX, IDC_SBITMAP_H, b_heading);
201         DDV_MinMaxInt(pDX, b_heading, 0, 359);
202         DDX_Text(pDX, IDC_SBITMAP_SCALE_X, b_scale_x);
203         DDV_MinMaxFloat(pDX, b_scale_x, 0.001f, 18.0f);
204         DDX_Text(pDX, IDC_SBITMAP_SCALE_Y, b_scale_y);
205         DDV_MinMaxFloat(pDX, b_scale_y, 0.001f, 18.0f);
206         DDX_Text(pDX, IDC_SBITMAP_DIV_X, b_div_x);
207         DDV_MinMaxInt(pDX, b_div_x, 1, 5);
208         DDX_Text(pDX, IDC_SBITMAP_DIV_Y, b_div_y);
209         DDV_MinMaxInt(pDX, b_div_y, 1, 5);
210
211         DDX_Check(pDX, IDC_POOF0, m_poof[0]);
212         DDX_Check(pDX, IDC_POOF1, m_poof[1]);
213         DDX_Check(pDX, IDC_POOF2, m_poof[2]);
214         DDX_Check(pDX, IDC_POOF3, m_poof[3]);
215         DDX_Check(pDX, IDC_POOF4, m_poof[4]);
216         DDX_Check(pDX, IDC_POOF5, m_poof[5]);
217         //}}AFX_DATA_MAP
218 }
219
220 BEGIN_MESSAGE_MAP(bg_bitmap_dlg, CDialog)
221         //{{AFX_MSG_MAP(bg_bitmap_dlg)
222         ON_WM_CLOSE()   
223         ON_CBN_SELCHANGE(IDC_NEBCOLOR, OnSelchangeNebcolor)
224         ON_CBN_SELCHANGE(IDC_NEBPATTERN, OnSelchangeNebpattern)
225         ON_BN_CLICKED(IDC_FULLNEB, OnFullNeb)
226         ON_WM_HSCROLL()
227
228         ON_LBN_SELCHANGE(IDC_SUN1_LIST, OnSunChange)
229         ON_CBN_SELCHANGE(IDC_SUN1, OnSunDropdownChange)
230         ON_BN_CLICKED(IDC_ADD_SUN, OnAddSun)
231         ON_BN_CLICKED(IDC_DEL_SUN, OnDelSun)
232
233         ON_LBN_SELCHANGE(IDC_SBITMAP_LIST, OnBitmapChange)
234         ON_CBN_SELCHANGE(IDC_SBITMAP, OnBitmapDropdownChange)
235         ON_BN_CLICKED(IDC_ADD_SBITMAP, OnAddBitmap)
236         ON_BN_CLICKED(IDC_DEL_SBITMAP, OnDelBitmap)
237         //}}AFX_MSG_MAP
238 END_MESSAGE_MAP()
239
240 /////////////////////////////////////////////////////////////////////////////
241 // bg_bitmap_dlg message handlers
242
243 void bg_bitmap_dlg::create()
244 {
245         char buf[40];
246         int i;
247         CComboBox *box;
248
249         CDialog::Create(bg_bitmap_dlg::IDD);
250         theApp.init_window(&Bg_wnd_data, this);
251         
252         box = (CComboBox *) GetDlgItem(IDC_NEBCOLOR);
253         for (i=0; i<NUM_NEBULA_COLORS; i++){
254                 box->AddString(Nebula_colors[i]);
255         }       
256
257         m_slider.SetRange(100, MAX_STARS);
258         m_slider.SetPos(Num_stars);
259         sprintf(buf, "%d", Num_stars);
260         GetDlgItem(IDC_TOTAL)->SetWindowText(buf);
261
262         build_nebfile_list();   
263
264         // setup neb poof names
265         GetDlgItem(IDC_POOF0)->SetWindowText(Neb2_poof_filenames[0]);   
266         GetDlgItem(IDC_POOF1)->SetWindowText(Neb2_poof_filenames[1]);
267         GetDlgItem(IDC_POOF2)->SetWindowText(Neb2_poof_filenames[2]);
268         GetDlgItem(IDC_POOF3)->SetWindowText(Neb2_poof_filenames[3]);
269         GetDlgItem(IDC_POOF4)->SetWindowText(Neb2_poof_filenames[4]);
270         GetDlgItem(IDC_POOF5)->SetWindowText(Neb2_poof_filenames[5]);
271         for(i=0; i<MAX_NEB2_BITMAPS; i++){
272                 if(strlen(Neb2_bitmap_filenames[i]) > 0){
273                         ((CComboBox*)GetDlgItem(IDC_NEB2_TEXTURE))->AddString(Neb2_bitmap_filenames[i]);
274                 }
275         }
276         // if we have a texture selected already
277         if(strlen(Neb2_texture_name) > 0){
278                 m_neb2_texture = ((CComboBox*)GetDlgItem(IDC_NEB2_TEXTURE))->SelectString(-1, Neb2_texture_name);
279                 if(m_neb2_texture == CB_ERR){
280                         ((CComboBox*)GetDlgItem(IDC_NEB2_TEXTURE))->SetCurSel(0);
281                         m_neb2_texture = 0;
282                 }
283         } else {
284                 ((CComboBox*)GetDlgItem(IDC_NEB2_TEXTURE))->SetCurSel(0);
285         }
286
287         // setup lightning storm names
288         ((CComboBox*)GetDlgItem(IDC_NEB2_LIGHTNING))->ResetContent();
289         ((CComboBox*)GetDlgItem(IDC_NEB2_LIGHTNING))->AddString(CString("none"));
290         for(i=0; i<Num_storm_types; i++){
291                 ((CComboBox*)GetDlgItem(IDC_NEB2_LIGHTNING))->AddString(CString(Storm_types[i].name));
292         }
293         ((CComboBox*)GetDlgItem(IDC_NEB2_LIGHTNING))->SelectString(-1, Mission_parse_storm_name);
294                 
295         // if the nebula intensity wasn't set before - set it now
296         if(Neb2_awacs < 0.0f){
297                 m_neb_intensity = CString("3000");
298         } else {
299                 char whee[255] = "";
300                 m_neb_intensity = CString(itoa((int)Neb2_awacs, whee, 10));
301         }
302                 
303         // determine if a full Neb2 is active - load in the full nebula filenames or the partial neb
304         // filenames
305         m_fullneb = (The_mission.flags & MISSION_FLAG_FULLNEB) ? 1 : 0;
306         if(m_fullneb){
307                 ((CButton*)GetDlgItem(IDC_FULLNEB))->SetCheck(1);                                       
308         } else {
309                 // since there is no "none" option for the full nebulas
310                 m_nebula_index = Nebula_index + 1;              
311         
312                 m_nebula_color = Mission_palette;
313                 if (Nebula_index < 0){
314                         GetDlgItem(IDC_NEBCOLOR)->EnableWindow(FALSE);
315                 }
316
317                 m_pitch = Nebula_pitch;
318                 m_bank = Nebula_bank;
319                 m_heading = Nebula_heading;
320         }
321
322         // setup sun and sunglow controls
323         sun_data_init();        
324
325         // setup bitmap info
326         bitmap_data_init();
327         
328         // determine if subspace is active
329         m_subspace = (The_mission.flags & MISSION_FLAG_SUBSPACE) ? 1 : 0;       
330
331         UpdateData(FALSE);
332         OnFullNeb();
333         update_data();
334         update_map_window();
335         set_modified();
336 }
337
338 void bg_bitmap_dlg::OnClose() 
339 {
340         UpdateData(TRUE);
341         Mission_palette = m_nebula_color;
342         
343         if(m_fullneb){          
344                 The_mission.flags |= MISSION_FLAG_FULLNEB;
345                 Neb2_awacs = (float)atoi((LPCSTR)m_neb_intensity);
346
347                 // override dumb values with reasonable ones
348                 if(Neb2_awacs <= 0.00000001f){
349                         Neb2_awacs = 3000.0f;
350                 }
351
352                 // store poof flags
353                 Neb2_poof_flags = 0;
354                 for(int idx=0; idx<MAX_NEB2_POOFS; idx++){
355                         if(m_poof[idx]){
356                                 Neb2_poof_flags |= (1<<idx);
357                         }
358                 }
359
360                 // get the bitmap name
361                 strcpy(Neb2_texture_name, Neb2_bitmap_filenames[m_neb2_texture]);
362
363                 // init the nebula
364                 neb2_level_init();
365         } else {
366                 The_mission.flags &= ~MISSION_FLAG_FULLNEB;
367                 Nebula_index = m_nebula_index - 1;
368                 Neb2_awacs = -1.0f;
369                 strcpy(Neb2_texture_name, "");
370         }
371
372         // get selected storm
373         ((CComboBox*)GetDlgItem(IDC_NEB2_LIGHTNING))->GetLBText(((CComboBox*)GetDlgItem(IDC_NEB2_LIGHTNING))->GetCurSel(), Mission_parse_storm_name);
374
375         Nebula_pitch = m_pitch;
376         Nebula_bank = m_bank;
377         Nebula_heading = m_heading;
378         if (Nebula_index >= 0){
379                 nebula_init(Nebula_filenames[Nebula_index], m_pitch, m_bank, m_heading);
380         } else {
381                 nebula_close();
382         }
383
384         if (m_subspace){
385                 The_mission.flags |= MISSION_FLAG_SUBSPACE;                             
386         } else {
387                 The_mission.flags &= ~MISSION_FLAG_SUBSPACE;            
388         }
389
390         // close sun data
391         sun_data_close();
392
393         // close bitmap data
394         bitmap_data_close();
395
396         theApp.record_window_data(&Bg_wnd_data, this);
397         delete Bg_bitmap_dialog;
398         Bg_bitmap_dialog = NULL;
399 }
400
401 void bg_bitmap_dlg::update_data(int update)
402 {
403         if (update){
404                 UpdateData(TRUE);
405         }
406
407         UpdateData(FALSE);      
408 }
409
410 void bg_bitmap_dlg::OnSelchangeNebcolor() 
411 {
412         CWaitCursor wait;
413
414         UpdateData(TRUE);
415         Mission_palette = m_nebula_color;
416
417
418         char palette_filename[1024];
419
420         Assert( Mission_palette >= 0 );
421         Assert( Mission_palette <= 98 );
422
423         sprintf( palette_filename, "gamepalette%d-%02d", 1, Mission_palette+1 );
424
425         mprintf(( "Loading palette %s\n", palette_filename ));
426
427         palette_load_table(palette_filename);
428         
429         Update_window = 1;
430 }
431
432 void bg_bitmap_dlg::OnSelchangeNebpattern() 
433 {
434         CWaitCursor wait;
435
436         UpdateData(TRUE);
437
438         // fullneb indexes differently  
439         Nebula_index = m_nebula_index - 1;                      
440
441         GetDlgItem(IDC_NEBCOLOR)->EnableWindow(m_nebula_index ? TRUE : FALSE);
442         if (Nebula_index >= 0){         
443                 nebula_init(Nebula_filenames[Nebula_index], m_pitch, m_bank, m_heading);                
444         } else {
445                 nebula_close();
446         }
447
448         Update_window = 1;
449 }
450
451 void bg_bitmap_dlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar *pScrollBar) 
452 {
453         char buf[40];
454
455         CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
456
457         MODIFY(Num_stars, m_slider.GetPos());
458         sprintf(buf, "%d", Num_stars);
459         GetDlgItem(IDC_TOTAL)->SetWindowText(buf);
460 }
461
462 // when the user toggled the "Full Nebula" button
463 void bg_bitmap_dlg::OnFullNeb()
464 {               
465         // determine what state we're in        
466         UpdateData(TRUE);
467         if(m_fullneb){
468                 // enable all fullneb controls
469                 GetDlgItem(IDC_NEB2_INTENSITY)->EnableWindow(TRUE);
470                 GetDlgItem(IDC_NEB2_TEXTURE)->EnableWindow(TRUE);
471                 GetDlgItem(IDC_NEB2_LIGHTNING)->EnableWindow(TRUE);
472                 GetDlgItem(IDC_POOF0)->EnableWindow(TRUE);
473                 GetDlgItem(IDC_POOF1)->EnableWindow(TRUE);
474                 GetDlgItem(IDC_POOF2)->EnableWindow(TRUE);
475                 GetDlgItem(IDC_POOF3)->EnableWindow(TRUE);
476                 GetDlgItem(IDC_POOF4)->EnableWindow(TRUE);
477                 GetDlgItem(IDC_POOF5)->EnableWindow(TRUE);                                              
478
479                 // disable non-fullneb controls
480                 GetDlgItem(IDC_NEBPATTERN)->EnableWindow(FALSE);
481                 GetDlgItem(IDC_NEBCOLOR)->EnableWindow(FALSE);
482                 GetDlgItem(IDC_PITCH)->EnableWindow(FALSE);
483                 GetDlgItem(IDC_BANK)->EnableWindow(FALSE);
484                 GetDlgItem(IDC_HEADING)->EnableWindow(FALSE);
485
486                 // check all relevant poofs             
487                 ((CButton*)GetDlgItem(IDC_POOF0))->SetCheck(FALSE);
488                 if(m_poof[0]){
489                         ((CButton*)GetDlgItem(IDC_POOF0))->SetCheck(TRUE);
490                 }
491                 ((CButton*)GetDlgItem(IDC_POOF1))->SetCheck(FALSE);
492                 if(m_poof[1]){
493                         ((CButton*)GetDlgItem(IDC_POOF1))->SetCheck(TRUE);
494                 }
495                 ((CButton*)GetDlgItem(IDC_POOF2))->SetCheck(FALSE);
496                 if(m_poof[2]){
497                         ((CButton*)GetDlgItem(IDC_POOF2))->SetCheck(TRUE);
498                 }
499                 ((CButton*)GetDlgItem(IDC_POOF3))->SetCheck(FALSE);
500                 if(m_poof[3]){
501                         ((CButton*)GetDlgItem(IDC_POOF3))->SetCheck(TRUE);
502                 }
503                 ((CButton*)GetDlgItem(IDC_POOF4))->SetCheck(FALSE);
504                 if(m_poof[4]){
505                         ((CButton*)GetDlgItem(IDC_POOF4))->SetCheck(TRUE);
506                 }
507                 ((CButton*)GetDlgItem(IDC_POOF5))->SetCheck(FALSE);
508                 if(m_poof[5]){
509                         ((CButton*)GetDlgItem(IDC_POOF5))->SetCheck(TRUE);
510                 }
511         } else {
512                 // enable all non-fullneb controls
513                 GetDlgItem(IDC_NEBPATTERN)->EnableWindow(TRUE);
514                 GetDlgItem(IDC_NEBCOLOR)->EnableWindow(TRUE);
515                 GetDlgItem(IDC_PITCH)->EnableWindow(TRUE);
516                 GetDlgItem(IDC_BANK)->EnableWindow(TRUE);
517                 GetDlgItem(IDC_HEADING)->EnableWindow(TRUE);            
518
519                 // disable all fullneb controls
520                 GetDlgItem(IDC_NEB2_INTENSITY)->EnableWindow(FALSE);
521                 GetDlgItem(IDC_NEB2_TEXTURE)->EnableWindow(FALSE);
522                 GetDlgItem(IDC_NEB2_LIGHTNING)->EnableWindow(FALSE);
523                 GetDlgItem(IDC_POOF0)->EnableWindow(FALSE);
524                 GetDlgItem(IDC_POOF1)->EnableWindow(FALSE);
525                 GetDlgItem(IDC_POOF2)->EnableWindow(FALSE);
526                 GetDlgItem(IDC_POOF3)->EnableWindow(FALSE);
527                 GetDlgItem(IDC_POOF4)->EnableWindow(FALSE);
528                 GetDlgItem(IDC_POOF5)->EnableWindow(FALSE);             
529         }               
530 }
531
532 // clear and build the nebula filename list appropriately
533 void bg_bitmap_dlg::build_nebfile_list()
534 {
535         int i;
536         CComboBox *box = (CComboBox *) GetDlgItem(IDC_NEBPATTERN);
537
538         // wacky
539         Assert(box != NULL);
540         if(box == NULL){
541                 return;
542         }
543         
544         // clear the box
545         box->ResetContent();
546
547         // add all necessary strings            
548         box->AddString("None");
549         for (i=0; i<NUM_NEBULAS; i++){
550                 box->AddString(Nebula_filenames[i]);
551         }       
552
553         // select the first elementccombobox
554         box->SetCurSel(0);
555         OnSelchangeNebpattern();
556 }
557
558 void bg_bitmap_dlg::sun_data_init()
559 {
560         int idx;
561
562         // force the range for pitch bank and heading
563         ((CSpinButtonCtrl *)GetDlgItem(IDC_SUN1_P_SPIN))->SetRange(0, 359);
564         ((CSpinButtonCtrl *)GetDlgItem(IDC_SUN1_B_SPIN))->SetRange(0, 359);
565         ((CSpinButtonCtrl *)GetDlgItem(IDC_SUN1_H_SPIN))->SetRange(0, 359);     
566
567         // add all suns to the drop down
568         idx=0;
569         while((idx < MAX_STARFIELD_BITMAPS) && (Sun_bitmaps[idx].bitmap != -1)){
570                 ((CComboBox*)GetDlgItem(IDC_SUN1))->AddString(Sun_bitmaps[idx].filename);
571                 
572                 // next
573                 idx++;
574         }
575         
576         // add all suns by bitmap filename to the list
577         for(idx=0; idx<Num_suns; idx++){        
578                 ((CListBox*)GetDlgItem(IDC_SUN1_LIST))->AddString(Suns[idx].filename);
579         }               
580
581         // if we have at least one item, select it
582         if(Num_suns > 0){
583                 ((CListBox*)GetDlgItem(IDC_SUN1_LIST))->SetCurSel(0);
584                 OnSunChange();
585         }
586 }
587
588 void bg_bitmap_dlg::sun_data_close()
589 {       
590         // if there is an active sun, save it
591         sun_data_save_current();        
592 }
593
594 void bg_bitmap_dlg::sun_data_save_current()
595 {       
596         // if we have an active item
597         if(s_index >= 0){
598                 // read out of the controls
599                 UpdateData(TRUE);
600
601                 // store the data
602                 strcpy(Suns[s_index].filename, (const char*)s_name);
603                 Suns[s_index].scale_x = (float)s_scale;
604                 Suns[s_index].scale_y = 1.0f;
605                 Suns[s_index].div_x = 1;
606                 Suns[s_index].div_y = 1;
607                 Suns[s_index].ang.p = (float)fl_radian(s_pitch);
608                 Suns[s_index].ang.b = (float)fl_radian(s_bank);
609                 Suns[s_index].ang.h = (float)fl_radian(s_heading);              
610         }
611 }
612
613 void bg_bitmap_dlg::OnSunChange()
614 {       
615         int drop_index;
616
617         // save the current sun
618         sun_data_save_current();
619
620         // select the new one
621         s_index = ((CListBox*)GetDlgItem(IDC_SUN1_LIST))->GetCurSel();
622
623         // setup data   
624         if(s_index >= 0){                               
625                 s_pitch = (int)fl_degrees(Suns[s_index].ang.p);
626                 s_bank = (int)fl_degrees(Suns[s_index].ang.b);
627                 s_heading = (int)fl_degrees(Suns[s_index].ang.h);
628                 s_scale = Suns[s_index].scale_x;                
629                 s_name = CString(Suns[s_index].filename);
630
631                 // stuff back into the controls
632                 UpdateData(FALSE);
633
634                 // select the proper item from the dropdown
635                 drop_index = ((CComboBox*)GetDlgItem(IDC_SUN1))->FindString( -1, Suns[s_index].filename );
636                 Assert(drop_index != CB_ERR);
637                 if(drop_index != CB_ERR){
638                         ((CComboBox*)GetDlgItem(IDC_SUN1))->SetCurSel(drop_index);
639                 }
640         }
641 }
642
643 void bg_bitmap_dlg::OnAddSun()
644 {
645         starfield_bitmap_instance *b;
646
647         // if we've already reached max suns
648         if(Num_suns >= MAX_STARFIELD_BITMAPS){
649                 MessageBox("Max suns reached!");
650                 return;
651         }
652
653         // save any current
654         sun_data_save_current();
655         
656         // select the first sun by default
657         b = &Suns[Num_suns++];
658         strcpy(b->filename, Sun_bitmaps[0].filename);
659         b->scale_x = 1.0f;
660         b->scale_y = 1.0f;
661         b->div_x = 1;
662         b->div_y = 1;
663         b->ang.p = 0;
664         b->ang.b = 0;
665         b->ang.h = 0;
666
667         // add to the listbox and select it
668         int add_index = ((CListBox*)GetDlgItem(IDC_SUN1_LIST))->AddString(b->filename);
669         ((CListBox*)GetDlgItem(IDC_SUN1_LIST))->SetCurSel(add_index);
670         
671         // call the OnSunChange function to setup all relvant data in the class
672         OnSunChange();
673 }
674
675 void bg_bitmap_dlg::OnDelSun()
676 {
677         int idx;
678
679         // if we don't have an active item
680         if(s_index < 0){
681                 return;
682         }
683         
684         // remove the item from the list
685         ((CListBox*)GetDlgItem(IDC_SUN1_LIST))->DeleteString(s_index);
686
687         // remove it from the list
688         for(idx=s_index; idx<Num_suns-1; idx++){
689                 Suns[idx] = Suns[idx+1];
690                 strcpy(Suns[idx].filename, Suns[idx+1].filename);
691         }
692
693         // decrement the count
694         Num_suns--;
695
696         // no item selected, let the message handler assign a new one
697         s_index = -1;
698 }
699
700 void bg_bitmap_dlg::OnSunDropdownChange()
701 {       
702         // if we have no active sun, do nothing
703         if(s_index < 0){
704                 return;
705         }
706
707         int new_index = ((CComboBox*)GetDlgItem(IDC_SUN1))->GetCurSel();
708         Assert(new_index != CB_ERR);
709
710         // get the new string
711         if(new_index != CB_ERR){
712                 ((CComboBox*)GetDlgItem(IDC_SUN1))->GetLBText(new_index, s_name);
713
714                 // change the name of the string in the listbox
715                 ((CListBox*)GetDlgItem(IDC_SUN1_LIST))->DeleteString(s_index);
716                 ((CListBox*)GetDlgItem(IDC_SUN1_LIST))->InsertString(s_index, (const char*)s_name);
717         }       
718 }
719
720 void bg_bitmap_dlg::bitmap_data_init()
721 {
722         int idx;
723
724         // force the range for pitch bank and heading
725         ((CSpinButtonCtrl *)GetDlgItem(IDC_SBITMAP_P_SPIN))->SetRange(0, 359);
726         ((CSpinButtonCtrl *)GetDlgItem(IDC_SBITMAP_B_SPIN))->SetRange(0, 359);
727         ((CSpinButtonCtrl *)GetDlgItem(IDC_SBITMAP_H_SPIN))->SetRange(0, 359);  
728
729         // add all suns to the drop down
730         idx=0;
731         while((idx < MAX_STARFIELD_BITMAPS) && (Starfield_bitmaps[idx].bitmap != -1)){
732                 ((CComboBox*)GetDlgItem(IDC_SBITMAP))->AddString(Starfield_bitmaps[idx].filename);
733                 
734                 // next
735                 idx++;
736         }
737         
738         // add all suns by bitmap filename to the list
739         for(idx=0; idx<Num_starfield_bitmaps; idx++){   
740                 ((CListBox*)GetDlgItem(IDC_SBITMAP_LIST))->AddString(Starfield_bitmap_instance[idx].filename);
741         }               
742
743         // if we have at least one item, select it
744         if(Num_starfield_bitmaps > 0){
745                 ((CListBox*)GetDlgItem(IDC_SBITMAP_LIST))->SetCurSel(0);
746                 OnBitmapChange();
747         }
748 }
749
750 void bg_bitmap_dlg::bitmap_data_close()
751 {
752         // if there is an active sun, save it
753         bitmap_data_save_current();     
754 }
755
756 void bg_bitmap_dlg::bitmap_data_save_current()
757 {
758         // if we have an active item
759         if(b_index >= 0){
760                 // read out of the controls
761                 UpdateData(TRUE);
762
763                 // store the data
764                 strcpy(Starfield_bitmap_instance[b_index].filename, (const char*)b_name);
765                 Starfield_bitmap_instance[b_index].scale_x = (float)b_scale_x;
766                 Starfield_bitmap_instance[b_index].scale_y = (float)b_scale_y;
767                 Starfield_bitmap_instance[b_index].div_x = b_div_x;
768                 Starfield_bitmap_instance[b_index].div_y = b_div_y;
769                 Starfield_bitmap_instance[b_index].ang.p = (float)fl_radian(b_pitch);
770                 Starfield_bitmap_instance[b_index].ang.b = (float)fl_radian(b_bank);
771                 Starfield_bitmap_instance[b_index].ang.h = (float)fl_radian(b_heading);
772         }
773 }
774
775 void bg_bitmap_dlg::OnBitmapChange()
776 {
777         int drop_index;
778
779         // save the current bitmap
780         bitmap_data_save_current();
781
782         // select the new one
783         b_index = ((CListBox*)GetDlgItem(IDC_SBITMAP_LIST))->GetCurSel();
784
785         // setup data   
786         if(b_index >= 0){               
787                 b_pitch = (int)fl_degrees(Starfield_bitmap_instance[b_index].ang.p);
788                 b_bank = (int)fl_degrees(Starfield_bitmap_instance[b_index].ang.b);
789                 b_heading = (int)fl_degrees(Starfield_bitmap_instance[b_index].ang.h);
790                 b_scale_x = Starfield_bitmap_instance[b_index].scale_x;
791                 b_scale_y = Starfield_bitmap_instance[b_index].scale_y;
792                 b_div_x = Starfield_bitmap_instance[b_index].div_x;
793                 b_div_y = Starfield_bitmap_instance[b_index].div_y;
794                 b_name = CString(Starfield_bitmap_instance[b_index].filename);
795
796                 // stuff back into the controls
797                 UpdateData(FALSE);
798
799                 // select the proper item from the dropdown
800                 drop_index = ((CComboBox*)GetDlgItem(IDC_SBITMAP))->FindString( -1, Starfield_bitmap_instance[b_index].filename );
801                 Assert(drop_index != CB_ERR);
802                 if(drop_index != CB_ERR){
803                         ((CComboBox*)GetDlgItem(IDC_SBITMAP))->SetCurSel(drop_index);
804                 }
805         }
806 }
807
808 void bg_bitmap_dlg::OnAddBitmap()
809 {
810         starfield_bitmap_instance *b;
811
812         // if we've already reached max bitmaps
813         if(Num_starfield_bitmaps >= MAX_STARFIELD_BITMAPS){
814                 MessageBox("Max starfield bitmaps reached!");
815                 return;
816         }
817
818         // save any current
819         bitmap_data_save_current();
820         
821         // select the first sun by default
822         b = &Starfield_bitmap_instance[Num_starfield_bitmaps++];
823         strcpy(b->filename, Starfield_bitmaps[0].filename);
824         b->scale_x = 1.0f;
825         b->scale_y = 1.0f;
826         b->div_x = 1;
827         b->div_y = 1;
828         b->ang.p = 0;
829         b->ang.b = 0;
830         b->ang.h = 0;
831
832         // add to the listbox and select it
833         int add_index = ((CListBox*)GetDlgItem(IDC_SBITMAP_LIST))->AddString(b->filename);
834         ((CListBox*)GetDlgItem(IDC_SBITMAP_LIST))->SetCurSel(add_index);
835         
836         // call the OnBitmapChange function to setup all relvant data in the class
837         OnBitmapChange();
838 }
839
840 void bg_bitmap_dlg::OnDelBitmap()
841 {
842         int idx;
843
844         // if we don't have an active item
845         if(b_index < 0){
846                 return;
847         }
848         
849         // remove the item from the list
850         ((CListBox*)GetDlgItem(IDC_SBITMAP_LIST))->DeleteString(b_index);
851
852         // remove it from the list
853         for(idx=b_index; idx<Num_starfield_bitmaps-1; idx++){
854                 Starfield_bitmap_instance[idx] = Starfield_bitmap_instance[idx+1];
855                 strcpy(Starfield_bitmap_instance[idx].filename, Starfield_bitmap_instance[idx+1].filename);
856         }
857
858         // decrement the count
859         Num_starfield_bitmaps--;
860
861         // no item selected, let the message handler assign a new one
862         b_index = -1;
863 }
864
865 void bg_bitmap_dlg::OnBitmapDropdownChange()
866 {
867         // if we have no active bitmap, do nothing
868         if(b_index < 0){
869                 return;
870         }
871
872         int new_index = ((CComboBox*)GetDlgItem(IDC_SBITMAP))->GetCurSel();
873         Assert(new_index != CB_ERR);
874
875         // get the new string
876         if(new_index != CB_ERR){
877                 ((CComboBox*)GetDlgItem(IDC_SBITMAP))->GetLBText(new_index, b_name);
878
879                 // change the name of the string in the listbox
880                 ((CListBox*)GetDlgItem(IDC_SBITMAP_LIST))->DeleteString(b_index);
881                 ((CListBox*)GetDlgItem(IDC_SBITMAP_LIST))->InsertString(b_index, (const char*)b_name);
882         }
883 }
884