]> git.xonotic.org Git - xonotic/netradiant.git/blob - contrib/bobtoolz/cportals.cpp
uncrustify! now the code is only ugly on the *inside*
[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         memset( this, 0, sizeof( CBspPortal ) );
32 }
33
34 CBspPortal::~CBspPortal(){
35         delete[] point;
36 }
37
38 void ClampFloat( float* p ){
39         double i;
40         double frac = modf( *p, &i );
41
42         if ( !frac ) {
43                 return;
44         }
45
46         if ( fabs( *p - ceil( *p ) ) < MAX_ROUND_ERROR ) {
47                 *p = ceilf( *p );
48         }
49
50         if ( fabs( *p - floor( *p ) ) < MAX_ROUND_ERROR ) {
51                 *p = floorf( *p );
52         }
53 }
54
55 bool CBspPortal::Build( char *def, unsigned int pointCnt, bool bInverse ){
56         char *c = def;
57         unsigned int n;
58
59         point_count = pointCnt;
60
61         if ( point_count < 3 ) {
62                 return FALSE;
63         }
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
75                 c++;
76
77                 int x;
78                 if ( bInverse ) {
79                         x = point_count - n - 1;
80                 }
81                 else{
82                         x = n;
83                 }
84
85                 sscanf( c, "%f %f %f", &point[x].p[0], &point[x].p[1], &point[x].p[2] );
86
87                 ClampFloat( &point[x].p[0] );
88                 ClampFloat( &point[x].p[1] );
89                 ClampFloat( &point[x].p[2] );
90         }
91
92         return TRUE;
93 }
94
95 CPortals::CPortals(){
96         memset( this, 0, sizeof( CPortals ) );
97 }
98
99 CPortals::~CPortals(){
100         Purge();
101 }
102
103 void CPortals::Purge(){
104         if ( node ) {
105                 delete[] node;
106         }
107         node = NULL;
108         node_count = 0;
109 }
110
111 void CPortals::Load(){
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                 Sys_Printf( "  ERROR - could not open file.\n" );
126
127                 return;
128         }
129
130         if ( !fgets( buf, LINE_BUF, in ) ) {
131                 fclose( in );
132
133                 Sys_Printf( "  ERROR - File ended prematurely.\n" );
134
135                 return;
136         }
137
138         if ( strncmp( "PRT1", buf, 4 ) != 0 ) {
139                 fclose( in );
140
141                 Sys_Printf( "  ERROR - File header indicates wrong file type (should be \"PRT1\").\n" );
142
143                 return;
144         }
145
146         if ( !fgets( buf, LINE_BUF, in ) ) {
147                 fclose( in );
148
149                 Sys_Printf( "  ERROR - File ended prematurely.\n" );
150
151                 return;
152         }
153
154         sscanf( buf, "%u", &node_count );
155
156         if ( node_count > 0xFFFF ) {
157                 fclose( in );
158
159                 node_count = 0;
160
161                 Sys_Printf( "  ERROR - Extreme number of nodes, aborting.\n" );
162
163                 return;
164         }
165
166         if ( !fgets( buf, LINE_BUF, in ) ) {
167                 fclose( in );
168
169                 node_count = 0;
170
171                 Sys_Printf( "  ERROR - File ended prematurely.\n" );
172
173                 return;
174         }
175
176         unsigned int p_count;
177         sscanf( buf, "%u", &p_count );
178
179         if ( !fgets( buf, LINE_BUF, in ) ) {
180                 fclose( in );
181
182                 node_count = 0;
183
184                 Sys_Printf( "  ERROR - File ended prematurely.\n" );
185
186                 return;
187         }
188
189         unsigned int p_count2;
190         sscanf( buf, "%u", &p_count2 );
191
192         node = new CBspNode[node_count];
193
194         unsigned int i;
195         for ( i = 0; i < p_count; i++ )
196         {
197                 if ( !fgets( buf, LINE_BUF, in ) ) {
198                         fclose( in );
199
200                         node_count = 0;
201
202                         Sys_Printf( "  ERROR - File ended prematurely.\n" );
203
204                         return;
205                 }
206
207                 unsigned int dummy, node1, node2;
208                 sscanf( buf, "%u %u %u", &dummy, &node1, &node2 );
209
210                 node[node1].portal_count++;
211                 node[node2].portal_count++;
212         }
213
214         for ( i = 0; i < p_count2; i++ )
215         {
216                 if ( !fgets( buf, LINE_BUF, in ) ) {
217                         fclose( in );
218
219                         node_count = 0;
220
221                         Sys_Printf( "  ERROR - File ended prematurely.\n" );
222
223                         return;
224                 }
225
226                 unsigned int dummy, node1;
227                 sscanf( buf, "%u %u", &dummy, &node1 );
228
229                 node[node1].portal_count++;
230         }
231
232         for ( i = 0; i < node_count; i++ )
233                 node[i].portal = new CBspPortal[node[i].portal_count];
234
235         fclose( in );
236
237         in = fopen( fn, "rt" );
238
239         fgets( buf, LINE_BUF, in );
240         fgets( buf, LINE_BUF, in );
241         fgets( buf, LINE_BUF, in );
242         fgets( buf, LINE_BUF, in );
243
244         unsigned int n;
245         for ( n = 0; n < p_count; n++ )
246         {
247                 if ( !fgets( buf, LINE_BUF, in ) ) {
248                         fclose( in );
249
250                         Purge();
251
252                         Sys_Printf( "  ERROR - Could not find information for portal number %d of %d.\n", n + 1, p_count );
253
254                         return;
255                 }
256
257                 unsigned int pCount, node1, node2;
258                 sscanf( buf, "%u %u %u", &pCount, &node1, &node2 );
259
260                 if ( !node[node1].AddPortal( buf, pCount, FALSE ) ) {
261                         fclose( in );
262
263                         Purge();
264
265                         Sys_Printf( "  ERROR - Information for portal number %d of %d is not formatted correctly.\n", n + 1, p_count );
266
267                         return;
268                 }
269
270                 if ( !node[node2].AddPortal( buf, pCount, TRUE ) ) {
271                         fclose( in );
272
273                         Purge();
274
275                         Sys_Printf( "  ERROR - Information for portal number %d of %d is not formatted correctly.\n", n + 1, p_count );
276
277                         return;
278                 }
279         }
280
281         for ( n = 0; n < p_count2; n++ )
282         {
283                 if ( !fgets( buf, LINE_BUF, in ) ) {
284                         fclose( in );
285
286                         Purge();
287
288                         Sys_Printf( "  ERROR - Could not find information for portal number %d of %d.\n", n + 1, p_count );
289
290                         return;
291                 }
292
293                 unsigned int pCount, node1;
294                 sscanf( buf, "%u %u", &pCount, &node1 );
295
296                 if ( !node[node1].AddPortal( buf, pCount, FALSE ) ) {
297                         fclose( in );
298
299                         Purge();
300
301                         Sys_Printf( "  ERROR - Information for portal number %d of %d is not formatted correctly.\n", n + 1, p_count );
302
303                         return;
304                 }
305         }
306
307         fclose( in );
308 }
309
310 CBspNode::CBspNode(){
311         portal = NULL;
312         portal_count = 0;
313         portal_next = 0;
314 }
315
316 CBspNode::~CBspNode(){
317         if ( portal != NULL ) {
318                 delete[] portal;
319         }
320 }
321
322 bool CBspNode::AddPortal( char *def, unsigned int pointCnt, bool bInverse ){
323         return portal[portal_next++].Build( def, pointCnt, bInverse );
324 }