]> git.xonotic.org Git - xonotic/netradiant.git/blob - contrib/bobtoolz/cportals.cpp
gcc: appease the hardening warnings
[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 "CPortals.h"
21
22 #include <string.h>
23 #include <math.h>
24 #include <cassert>
25
26 #include "misc.h"
27
28 const int LINE_BUF = 1000;
29 const char *MSG_PREFIX = "bobToolz plugin: ";
30
31 // these classes are far less of a mess than my code was,
32 // thanq to G.DeWan 4 the prtview source on which it was based
33
34 CBspPortal::CBspPortal()
35 {
36     memset(this, 0, sizeof(CBspPortal));
37 }
38
39 CBspPortal::~CBspPortal()
40 {
41     delete[] point;
42 }
43
44 void ClampFloat(float *p)
45 {
46     double i;
47     double frac = modf(*p, &i);
48
49     if (!frac) {
50         return;
51     }
52
53     if (fabs(*p - ceil(*p)) < MAX_ROUND_ERROR) {
54         *p = static_cast<float>( ceil(*p));
55     }
56
57     if (fabs(*p - floor(*p)) < MAX_ROUND_ERROR) {
58         *p = static_cast<float>( floor(*p));
59     }
60 }
61
62 bool CBspPortal::Build(char *def, unsigned int pointCnt, bool bInverse)
63 {
64     char *c = def;
65     unsigned int n;
66
67     point_count = pointCnt;
68
69     if (point_count < 3) {
70         return false;
71     }
72
73     point = new CBspPoint[point_count];
74
75     for (n = 0; n < point_count; n++) {
76         for (; *c != 0 && *c != '('; c++) {}
77
78         if (*c == 0) {
79             return false;
80         }
81
82         c++;
83
84         int x;
85         if (bInverse) {
86             x = point_count - n - 1;
87         } else {
88             x = n;
89         }
90
91         sscanf(c, "%f %f %f", &point[x].p[0], &point[x].p[1], &point[x].p[2]);
92
93         ClampFloat(&point[x].p[0]);
94         ClampFloat(&point[x].p[1]);
95         ClampFloat(&point[x].p[2]);
96     }
97
98     return true;
99 }
100
101 CPortals::CPortals()
102 {
103     memset(this, 0, sizeof(CPortals));
104 }
105
106 CPortals::~CPortals()
107 {
108     Purge();
109 }
110
111 void CPortals::Purge()
112 {
113     if (node) {
114         delete[] node;
115     }
116     node = NULL;
117     node_count = 0;
118 }
119
120 void CPortals::Load()
121 {
122     char buf[LINE_BUF + 1];
123
124     memset(buf, 0, LINE_BUF + 1);
125
126     Purge();
127
128     globalOutputStream() << MSG_PREFIX << "Loading portal file " << fn << ".\n";
129
130     FILE *in;
131
132     in = fopen(fn, "rt");
133
134     if (in == NULL) {
135         globalOutputStream() << "  ERROR - could not open file.\n";
136
137         return;
138     }
139
140     if (!fgets(buf, LINE_BUF, in)) {
141         fclose(in);
142
143         globalOutputStream() << "  ERROR - File ended prematurely.\n";
144
145         return;
146     }
147
148     if (strncmp("PRT1", buf, 4) != 0) {
149         fclose(in);
150
151         globalOutputStream() << "  ERROR - File header indicates wrong file type (should be \"PRT1\").\n";
152
153         return;
154     }
155
156     if (!fgets(buf, LINE_BUF, in)) {
157         fclose(in);
158
159         globalOutputStream() << "  ERROR - File ended prematurely.\n";
160
161         return;
162     }
163
164     sscanf(buf, "%u", &node_count);
165
166     if (node_count > 0xFFFF) {
167         fclose(in);
168
169         node_count = 0;
170
171         globalOutputStream() << "  ERROR - Extreme number of nodes, aborting.\n";
172
173         return;
174     }
175
176     if (!fgets(buf, LINE_BUF, in)) {
177         fclose(in);
178
179         node_count = 0;
180
181         globalOutputStream() << "  ERROR - File ended prematurely.\n";
182
183         return;
184     }
185
186     unsigned int p_count;
187     sscanf(buf, "%u", &p_count);
188
189     if (!fgets(buf, LINE_BUF, in)) {
190         fclose(in);
191
192         node_count = 0;
193
194         globalOutputStream() << "  ERROR - File ended prematurely.\n";
195
196         return;
197     }
198
199     unsigned int p_count2;
200     sscanf(buf, "%u", &p_count2);
201
202     node = new CBspNode[node_count];
203
204     unsigned int i;
205     for (i = 0; i < p_count; i++) {
206         if (!fgets(buf, LINE_BUF, in)) {
207             fclose(in);
208
209             node_count = 0;
210
211             globalOutputStream() << "  ERROR - File ended prematurely.\n";
212
213             return;
214         }
215
216         unsigned int dummy, node1, node2;
217         sscanf(buf, "%u %u %u", &dummy, &node1, &node2);
218
219         node[node1].portal_count++;
220         node[node2].portal_count++;
221     }
222
223     for (i = 0; i < p_count2; i++) {
224         if (!fgets(buf, LINE_BUF, in)) {
225             fclose(in);
226
227             node_count = 0;
228
229             globalOutputStream() << "  ERROR - File ended prematurely.\n";
230
231             return;
232         }
233
234         unsigned int dummy, node1;
235         sscanf(buf, "%u %u", &dummy, &node1);
236
237         node[node1].portal_count++;
238     }
239
240     for (i = 0; i < node_count; i++) {
241         node[i].portal = new CBspPortal[node[i].portal_count];
242     }
243
244     fclose(in);
245
246     in = fopen(fn, "rt");
247
248     assert(fgets(buf, LINE_BUF, in));
249     assert(fgets(buf, LINE_BUF, in));
250     assert(fgets(buf, LINE_BUF, in));
251     assert(fgets(buf, LINE_BUF, in));
252
253     unsigned int n;
254     for (n = 0; n < p_count; n++) {
255         if (!fgets(buf, LINE_BUF, in)) {
256             fclose(in);
257
258             Purge();
259
260             globalOutputStream() << "  ERROR - Could not find information for portal number " << n + 1 << " of "
261                                  << p_count << ".\n";
262
263             return;
264         }
265
266         unsigned int pCount, node1, node2;
267         sscanf(buf, "%u %u %u", &pCount, &node1, &node2);
268
269         if (!node[node1].AddPortal(buf, pCount, false)) {
270             fclose(in);
271
272             Purge();
273
274             globalOutputStream() << "  ERROR - Information for portal number " << n + 1 << " of " << p_count
275                                  << " is not formatted correctly.\n";
276
277             return;
278         }
279
280         if (!node[node2].AddPortal(buf, pCount, true)) {
281             fclose(in);
282
283             Purge();
284
285             globalOutputStream() << "  ERROR - Information for portal number " << n + 1 << " of " << p_count
286                                  << " is not formatted correctly.\n";
287
288             return;
289         }
290     }
291
292     for (n = 0; n < p_count2; n++) {
293         if (!fgets(buf, LINE_BUF, in)) {
294             fclose(in);
295
296             Purge();
297
298             globalOutputStream() << "  ERROR - Could not find information for portal number " << n + 1 << " of "
299                                  << p_count << ".\n";
300
301             return;
302         }
303
304         unsigned int pCount, node1;
305         sscanf(buf, "%u %u", &pCount, &node1);
306
307         if (!node[node1].AddPortal(buf, pCount, false)) {
308             fclose(in);
309
310             Purge();
311
312             globalOutputStream() << "  ERROR - Information for portal number " << n + 1 << " of " << p_count
313                                  << " is not formatted correctly.\n";
314
315             return;
316         }
317     }
318
319     fclose(in);
320 }
321
322 CBspNode::CBspNode()
323 {
324     portal = NULL;
325     portal_count = 0;
326     portal_next = 0;
327 }
328
329 CBspNode::~CBspNode()
330 {
331     if (portal != NULL) {
332         delete[] portal;
333     }
334 }
335
336 bool CBspNode::AddPortal(char *def, unsigned int pointCnt, bool bInverse)
337 {
338     return portal[portal_next++].Build(def, pointCnt, bInverse);
339 }