]> icculus.org git repositories - taylor/freespace2.git/blob - src/fred2/orienteditor.cpp
fix issue with looping audio streams
[taylor/freespace2.git] / src / fred2 / orienteditor.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 /*
10  * $Logfile: /Freespace2/code/FRED2/OrientEditor.cpp $
11  * $Revision$
12  * $Date$
13  * $Author$
14  *
15  * Object orientation editor (or just object editor) dialog box handling code
16  *
17  * $Log$
18  * Revision 1.3  2002/06/09 04:41:16  relnev
19  * added copyright header
20  *
21  * Revision 1.2  2002/05/07 03:16:44  theoddone33
22  * The Great Newline Fix
23  *
24  * Revision 1.1.1.1  2002/05/03 03:28:08  root
25  * Initial import.
26  *
27  * 
28  * 2     10/07/98 6:28p Dave
29  * Initial checkin. Renamed all relevant stuff to be Fred2 instead of
30  * Fred. Globalized mission and campaign file extensions. Removed Silent
31  * Threat specific code.
32  * 
33  * 1     10/07/98 3:02p Dave
34  * 
35  * 1     10/07/98 3:00p Dave
36  * 
37  * 18    7/13/98 10:04a Hoffoss
38  * Fixed bug where jump nodes in mission would screw up indexing.
39  * 
40  * 17    3/12/98 2:21p Johnson
41  * Fixed some Fred bugs related to jump nodes.
42  * 
43  * 16    9/16/97 9:41p Hoffoss
44  * Changed Fred code around to stop using Parse_player structure for
45  * player information, and use actual ships instead.
46  * 
47  * 15    8/16/97 2:02a Hoffoss
48  * Made docked objects move together in Fred.
49  * 
50  * 14    8/15/97 8:24p Hoffoss
51  * Fixed bug with orient editor.
52  * 
53  * 13    8/14/97 3:14p Hoffoss
54  * Fixed name displayed for players.
55  * 
56  * 12    7/29/97 2:20p Hoffoss
57  * Fixed some minor bugs.
58  * 
59  * 11    6/26/97 11:18a Hoffoss
60  * Fixed bug in orient editor.  OBJ_POINT type wasn't accounted for.
61  * 
62  * 10    5/20/97 2:28p Hoffoss
63  * Added message box queries for close window operation on all modal
64  * dialog boxes.
65  * 
66  * 9     5/14/97 4:08p Lawrance
67  * removing my_index from game arrays
68  * 
69  * 8     4/17/97 2:01p Hoffoss
70  * All dialog box window states are saved between sessions now.
71  * 
72  * 7     3/12/97 4:33p Hoffoss
73  * added spin controls to orient editor, light intensity level can be
74  * specified in BG editor.
75  * 
76  * 6     2/28/97 11:31a Hoffoss
77  * Implemented modeless dialog saving and restoring, and changed some
78  * variables names.
79  * 
80  * 5     2/21/97 5:34p Hoffoss
81  * Added extensive modification detection and fixed a bug in initial
82  * orders editor.
83  * 
84  * 4     2/17/97 5:28p Hoffoss
85  * Checked RCS headers, added them were missing, changing description to
86  * something better, etc where needed.
87  *
88  * $NoKeywords: $
89  */
90
91 #include "stdafx.h"
92 #include "fred.h"
93 #include "orienteditor.h"
94 #include "management.h"
95 #include "linklist.h"
96 #include "fredview.h"
97
98 #ifdef _DEBUG
99 #define new DEBUG_NEW
100 #undef THIS_FILE
101 static char THIS_FILE[] = __FILE__;
102 #endif
103
104 #define PREC    0.0001f
105
106 /////////////////////////////////////////////////////////////////////////////
107 // orient_editor dialog
108
109 orient_editor::orient_editor(CWnd* pParent /*=NULL*/)
110         : CDialog(orient_editor::IDD, pParent)
111 {
112         vector pos;
113
114         //{{AFX_DATA_INIT(orient_editor)
115         m_object_index = 0;
116         m_point_to = FALSE;
117         m_position_z = _T("");
118         m_position_y = _T("");
119         m_position_x = _T("");
120         m_location_x = _T("0.0");
121         m_location_y = _T("0.0");
122         m_location_z = _T("0.0");
123         //}}AFX_DATA_INIT
124         SDL_assert(query_valid_object());
125         pos = Objects[cur_object_index].pos;
126         m_position_x.Format("%.1f", pos.x);
127         m_position_y.Format("%.1f", pos.y);
128         m_position_z.Format("%.1f", pos.z);
129 }
130
131 void orient_editor::DoDataExchange(CDataExchange* pDX)
132 {
133         CDialog::DoDataExchange(pDX);
134         //{{AFX_DATA_MAP(orient_editor)
135         DDX_Control(pDX, IDC_SPIN6, m_spin6);
136         DDX_Control(pDX, IDC_SPIN5, m_spin5);
137         DDX_Control(pDX, IDC_SPIN4, m_spin4);
138         DDX_Control(pDX, IDC_SPIN3, m_spin3);
139         DDX_Control(pDX, IDC_SPIN2, m_spin2);
140         DDX_Control(pDX, IDC_SPIN1, m_spin1);
141         DDX_CBIndex(pDX, IDC_OBJECT_LIST, m_object_index);
142         DDX_Check(pDX, IDC_POINT_TO_CHECKBOX, m_point_to);
143         DDX_Text(pDX, IDC_POSITION_Z, m_position_z);
144         DDX_Text(pDX, IDC_POSITION_Y, m_position_y);
145         DDX_Text(pDX, IDC_POSITION_X, m_position_x);
146         DDX_Text(pDX, IDC_LOCATION_X, m_location_x);
147         DDX_Text(pDX, IDC_LOCATION_Y, m_location_y);
148         DDX_Text(pDX, IDC_LOCATION_Z, m_location_z);
149         //}}AFX_DATA_MAP
150 }
151
152 BEGIN_MESSAGE_MAP(orient_editor, CDialog)
153         //{{AFX_MSG_MAP(orient_editor)
154         ON_WM_CLOSE()
155         //}}AFX_MSG_MAP
156 END_MESSAGE_MAP()
157
158 /////////////////////////////////////////////////////////////////////////////
159 // orient_editor message handlers
160
161 BOOL orient_editor::OnInitDialog() 
162 {
163         char text[80];
164         int type;
165         CComboBox *box;
166         object *ptr;
167
168         CDialog::OnInitDialog();
169         theApp.init_window(&Object_wnd_data, this);
170         ((CButton *) GetDlgItem(IDC_POINT_TO_OBJECT))->SetCheck(1);
171         box = (CComboBox *) GetDlgItem(IDC_OBJECT_LIST);
172         box->ResetContent();
173
174         total = 0;
175         ptr = GET_FIRST(&obj_used_list);
176         while (ptr != END_OF_LIST(&obj_used_list)) {
177                 if (Marked != 1 || OBJ_INDEX(ptr) != cur_object_index) {
178                         if ((ptr->type == OBJ_START) || (ptr->type == OBJ_SHIP)) {
179                                 box->AddString(Ships[ptr->instance].ship_name);
180                                 index[total++] = OBJ_INDEX(ptr);
181
182                         } else if (ptr->type == OBJ_WAYPOINT) {
183                                 sprintf(text, "%s:%d", Waypoint_lists[ptr->instance / 65536].name,
184                                         (ptr->instance & 0xffff) + 1);
185
186                                 box->AddString(text);
187                                 index[total++] = OBJ_INDEX(ptr);
188
189                         } else if ((ptr->type == OBJ_POINT) || (ptr->type == OBJ_JUMP_NODE)) {
190                         } else
191                                 SDL_assert(0);  // unknown object type.
192                 }
193
194                 ptr = GET_NEXT(ptr);
195         }
196
197         type = Objects[cur_object_index].type;
198         if (Marked == 1 && type == OBJ_WAYPOINT) {
199                 GetDlgItem(IDC_POINT_TO_CHECKBOX)->EnableWindow(0);
200                 GetDlgItem(IDC_POINT_TO_OBJECT)->EnableWindow(0);
201                 GetDlgItem(IDC_POINT_TO_LOCATION)->EnableWindow(0);
202                 GetDlgItem(IDC_OBJECT_LIST)->EnableWindow(0);
203                 GetDlgItem(IDC_LOCATION_X)->EnableWindow(0);
204                 GetDlgItem(IDC_LOCATION_Y)->EnableWindow(0);
205                 GetDlgItem(IDC_LOCATION_Z)->EnableWindow(0);
206                 m_object_index = -1;
207
208         } else {
209                 m_object_index = 0;
210         }
211
212         m_spin1.SetRange(99999, -99999);
213         m_spin1.SetPos((int) convert(m_position_x));
214         m_spin2.SetRange(99999, -99999);
215         m_spin2.SetPos((int) convert(m_position_y));
216         m_spin3.SetRange(99999, -99999);
217         m_spin3.SetPos((int) convert(m_position_z));
218         m_spin4.SetRange(99999, -99999);
219         m_spin5.SetRange(99999, -99999);
220         m_spin6.SetRange(99999, -99999);
221         UpdateData(FALSE);
222         return TRUE;
223 }
224
225 int orient_editor::query_modified()
226 {
227         float dif;
228
229         dif = Objects[cur_object_index].pos.x - convert(m_position_x);
230         if ((dif > PREC) || (dif < -PREC))
231                 return 1;
232         dif = Objects[cur_object_index].pos.y - convert(m_position_y);
233         if ((dif > PREC) || (dif < -PREC))
234                 return 1;
235         dif = Objects[cur_object_index].pos.z - convert(m_position_z);
236         if ((dif > PREC) || (dif < -PREC))
237                 return 1;
238
239         if (((CButton *) GetDlgItem(IDC_POINT_TO_CHECKBOX))->GetCheck() == 1)
240                 return 1;
241
242         return 0;
243 }
244
245 void orient_editor::OnOK()
246 {
247         vector delta, pos;
248         object *ptr;
249
250         UpdateData(TRUE);
251         pos.x = convert(m_position_x);
252         pos.y = convert(m_position_y);
253         pos.z = convert(m_position_z);
254
255         if ((((CButton *) GetDlgItem(IDC_POINT_TO_OBJECT))->GetCheck() == 1) ||
256                 (((CButton *) GetDlgItem(IDC_POINT_TO_LOCATION))->GetCheck() == 1))
257                         set_modified();
258
259         vm_vec_sub(&delta, &pos, &Objects[cur_object_index].pos);
260         if (delta.x || delta.y || delta.z)
261                 set_modified();
262
263         ptr = GET_FIRST(&obj_used_list);
264         while (ptr != END_OF_LIST(&obj_used_list)) {
265                 if (ptr->flags & OF_MARKED) {
266                         vm_vec_add2(&ptr->pos, &delta);
267                         update_object(ptr);
268                 }
269
270                 ptr = GET_NEXT(ptr);
271         }
272
273         ptr = GET_FIRST(&obj_used_list);
274         while (ptr != END_OF_LIST(&obj_used_list)) {
275                 if (ptr->flags & OF_MARKED)
276                         object_moved(ptr);
277
278                 ptr = GET_NEXT(ptr);
279         }
280
281         theApp.record_window_data(&Object_wnd_data, this);
282         CDialog::OnOK();
283 }
284
285 void orient_editor::update_object(object *ptr)
286 {
287         if (ptr->type != OBJ_WAYPOINT && m_point_to) {
288                 vector v, loc;
289                 matrix m;
290
291                 memset(&v, 0, sizeof(vector));
292                 loc.x = convert(m_location_x);
293                 loc.y = convert(m_location_y);
294                 loc.z = convert(m_location_z);
295                 if (((CButton *) GetDlgItem(IDC_POINT_TO_OBJECT))->GetCheck() == 1) {
296                         v = Objects[index[m_object_index]].pos;
297                         vm_vec_sub2(&v, &ptr->pos);
298
299                 } else if (((CButton *) GetDlgItem(IDC_POINT_TO_LOCATION))->GetCheck() == 1) {
300                         vm_vec_sub(&v, &loc, &ptr->pos);
301
302                 } else {
303                         SDL_assert(0);  // neither radio button is checked.
304                 }
305
306                 if (!v.x && !v.y && !v.z){
307                         return;  // can't point to itself.
308                 }
309
310                 vm_vector_2_matrix(&m, &v, NULL, NULL);
311                 ptr->orient = m;
312         }
313 }
314
315 float orient_editor::convert(CString &str)
316 {
317         char buf[256];
318         int i, j, len;
319
320         string_copy(buf, str, 255);
321         len = strlen(buf);
322         for (i=j=0; i<len; i++)
323                 if (buf[i] != ',')
324                         buf[j++] = buf[i];
325
326         buf[j] = 0;
327         return (float) atof(buf);
328 }
329
330 void orient_editor::OnCancel()
331 {
332         theApp.record_window_data(&Object_wnd_data, this);
333         CDialog::OnCancel();
334 }
335
336 void orient_editor::OnClose() 
337 {
338         int z;
339
340         if (query_modified()) {
341                 z = MessageBox("Do you want to keep your changes?", "Close", MB_ICONQUESTION | MB_YESNOCANCEL);
342                 if (z == IDCANCEL)
343                         return;
344
345                 if (z == IDYES) {
346                         OnOK();
347                         return;
348                 }
349         }
350
351         CDialog::OnClose();
352 }
353