more eol-style
[xonotic/netradiant.git] / contrib / bobtoolz / cportals.cpp
1 /*
2 BobToolz plugin for GtkRadiant
3 Copyright (C) 2001 Gordon Biggans
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 */
19
20 #include "StdAfx.h"
21 #include "CPortals.h"
22 #include "misc.h"
23
24 #define LINE_BUF 1000
25 #define MSG_PREFIX "bobToolz plugin: "
26
27 // these classes are far less of a mess than my code was, 
28 // thanq to G.DeWan 4 the prtview source on which it was based
29
30 CBspPortal::CBspPortal()
31 {
32         memset(this, 0, sizeof(CBspPortal));
33 }
34
35 CBspPortal::~CBspPortal()
36 {
37         delete[] point;
38 }
39
40 void ClampFloat(float* p)
41 {
42         double i;
43         double frac = modf(*p, &i);
44
45         if(!frac)
46                 return;
47
48         if(fabs(*p - ceil(*p)) < MAX_ROUND_ERROR)
49                 *p = ceilf(*p);
50
51         if(fabs(*p - floor(*p)) < MAX_ROUND_ERROR)
52                 *p = floorf(*p);
53 }
54
55 bool CBspPortal::Build(char *def, unsigned int pointCnt, bool bInverse)
56 {
57         char *c = def;
58         unsigned int n;
59
60         point_count = pointCnt;
61
62         if(point_count < 3)
63                 return FALSE;
64
65         point = new CBspPoint[point_count];
66
67         for(n = 0; n < point_count; n++)
68         {
69                 for(; *c != 0 && *c != '('; c++);
70
71                 if(*c == 0)
72                         return FALSE;
73
74                 c++;
75
76                 int x;
77                 if(bInverse)
78                         x = point_count - n - 1;
79                 else
80                         x = n;
81
82                 sscanf(c, "%f %f %f", &point[x].p[0], &point[x].p[1], &point[x].p[2]);
83
84                 ClampFloat(&point[x].p[0]);
85                 ClampFloat(&point[x].p[1]);
86                 ClampFloat(&point[x].p[2]);
87         }
88
89         return TRUE;
90 }
91
92 CPortals::CPortals()
93 {
94         memset(this, 0, sizeof(CPortals));
95 }
96
97 CPortals::~CPortals()
98 {
99         Purge();
100 }
101
102 void CPortals::Purge()
103 {
104         if(node)
105                 delete[] node;
106         node = NULL;
107         node_count = 0;
108 }
109
110 void CPortals::Load()
111 {
112         char buf[LINE_BUF+1];
113
114         memset(buf, 0, LINE_BUF + 1);
115         
116         Purge();
117
118         Sys_Printf(MSG_PREFIX "Loading portal file %s.\n", fn);
119
120         FILE *in;
121
122         in = fopen(fn, "rt");
123
124         if(in == NULL)
125         {
126                 Sys_Printf("  ERROR - could not open file.\n");
127
128                 return;
129         }
130
131         if(!fgets(buf, LINE_BUF, in))
132         {
133                 fclose(in);
134
135                 Sys_Printf("  ERROR - File ended prematurely.\n");
136
137                 return;
138         }
139
140         if(strncmp("PRT1", buf, 4) != 0)
141         {
142                 fclose(in);
143
144                 Sys_Printf("  ERROR - File header indicates wrong file type (should be \"PRT1\").\n");
145
146                 return;
147         }
148
149         if(!fgets(buf, LINE_BUF, in))
150         {
151                 fclose(in);
152
153                 Sys_Printf("  ERROR - File ended prematurely.\n");
154
155                 return;
156         }
157
158         sscanf(buf, "%u", &node_count);
159
160         if(node_count > 0xFFFF)
161         {
162                 fclose(in);
163
164                 node_count = 0;
165
166                 Sys_Printf("  ERROR - Extreme number of nodes, aborting.\n");
167
168                 return;
169         }
170
171         if(!fgets(buf, LINE_BUF, in))
172         {
173                 fclose(in);
174
175                 node_count = 0;
176
177                 Sys_Printf("  ERROR - File ended prematurely.\n");
178
179                 return;
180         }
181
182         unsigned int p_count;
183         sscanf(buf, "%u", &p_count);
184
185         if(!fgets(buf, LINE_BUF, in))
186         {
187                 fclose(in);
188
189                 node_count = 0;
190
191                 Sys_Printf("  ERROR - File ended prematurely.\n");
192
193                 return;
194         }
195
196         unsigned int p_count2;
197         sscanf(buf, "%u", &p_count2);
198
199         node = new CBspNode[node_count];
200
201         unsigned int i;
202         for(i = 0; i < p_count; i++)
203         {
204                 if(!fgets(buf, LINE_BUF, in))
205                 {
206                         fclose(in);
207
208                         node_count = 0;
209
210                         Sys_Printf("  ERROR - File ended prematurely.\n");
211
212                         return;
213                 }
214
215                 unsigned int dummy, node1, node2;
216                 sscanf(buf, "%u %u %u", &dummy, &node1, &node2);
217
218                 node[node1].portal_count++;
219                 node[node2].portal_count++;
220         }
221
222         for(i = 0; i < p_count2; i++)
223         {
224                 if(!fgets(buf, LINE_BUF, in))
225                 {
226                         fclose(in);
227
228                         node_count = 0;
229
230                         Sys_Printf("  ERROR - File ended prematurely.\n");
231
232                         return;
233                 }
234
235                 unsigned int dummy, node1;
236                 sscanf(buf, "%u %u", &dummy, &node1);
237
238                 node[node1].portal_count++;
239         }
240
241         for(i = 0; i < node_count; i++)
242                 node[i].portal = new CBspPortal[node[i].portal_count];
243
244         fclose(in);
245
246         in = fopen(fn, "rt");
247
248         fgets(buf, LINE_BUF, in);
249         fgets(buf, LINE_BUF, in);
250         fgets(buf, LINE_BUF, in);
251         fgets(buf, LINE_BUF, in);
252
253         unsigned int n;
254         for(n = 0; n < p_count; n++)
255         {
256                 if(!fgets(buf, LINE_BUF, in))
257                 {
258                         fclose(in);
259
260                         Purge();
261
262                         Sys_Printf("  ERROR - Could not find information for portal number %d of %d.\n", n + 1, p_count);
263
264                         return;
265                 }
266
267                 unsigned int pCount, node1, node2;
268                 sscanf(buf, "%u %u %u", &pCount, &node1, &node2);
269
270                 if(!node[node1].AddPortal(buf, pCount, FALSE))
271                 {
272                         fclose(in);
273
274                         Purge();
275
276                         Sys_Printf("  ERROR - Information for portal number %d of %d is not formatted correctly.\n", n + 1, p_count);
277
278                         return;
279                 }
280
281                 if(!node[node2].AddPortal(buf, pCount, TRUE))
282                 {
283                         fclose(in);
284
285                         Purge();
286
287                         Sys_Printf("  ERROR - Information for portal number %d of %d is not formatted correctly.\n", n + 1, p_count);
288
289                         return;
290                 }
291         }
292
293  for(n = 0; n < p_count2; n++)
294         {
295                 if(!fgets(buf, LINE_BUF, in))
296                 {
297                         fclose(in);
298
299                         Purge();
300
301                         Sys_Printf("  ERROR - Could not find information for portal number %d of %d.\n", n + 1, p_count);
302
303                         return;
304                 }
305
306                 unsigned int pCount, node1;
307                 sscanf(buf, "%u %u", &pCount, &node1);
308
309                 if(!node[node1].AddPortal(buf, pCount, FALSE))
310                 {
311                         fclose(in);
312
313                         Purge();
314
315                         Sys_Printf("  ERROR - Information for portal number %d of %d is not formatted correctly.\n", n + 1, p_count);
316
317                         return;
318                 }
319         }
320
321         fclose(in);
322 }
323
324 CBspNode::CBspNode()
325 {
326         portal = NULL;
327         portal_count = 0;
328         portal_next = 0;
329 }
330
331 CBspNode::~CBspNode()
332 {
333         if(portal != NULL)
334                 delete[] portal;
335 }
336
337 bool CBspNode::AddPortal(char *def, unsigned int pointCnt, bool bInverse)
338 {
339         return portal[portal_next++].Build(def, pointCnt, bInverse);
340 }