]> git.xonotic.org Git - xonotic/netradiant.git/blob - contrib/gtkgensurf/genmap.cpp
uncrustify! now the code is only ugly on the *inside*
[xonotic/netradiant.git] / contrib / gtkgensurf / genmap.cpp
1 /*
2    GenSurf plugin for GtkRadiant
3    Copyright (C) 2001 David Hyde, Loki software and qeradiant.com
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 <math.h>
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include "gensurf.h"
24
25 double xmin,xmax,ymin,ymax,zmin,zmax;
26 double backface;
27 extern double dh, dv;
28 FILE  *fmap;
29 XYZ xyz[MAX_ROWS + 1][MAX_ROWS + 1];
30 int contents;
31 int surface[3];
32 LPVOID h_func_group;
33 LPVOID terrainkey;  // ^Fishman - Add terrain key to func_group.
34
35 //=============================================================
36 // Hydra : snap-to-grid begin
37 double CalculateSnapValue( double value ){
38         long snapvalue;
39
40         // simple uncomplicated snapping, rounding both UP and DOWN to the nearest
41         // grid unit.
42         if ( SnapToGrid > 0 ) {
43                 snapvalue = (int)value / SnapToGrid;
44                 if ( (long)value % SnapToGrid < ( SnapToGrid / 2 ) ) { // Snap Downwards if less than halfway between to grid units
45                         value = snapvalue * SnapToGrid;
46                 }
47                 else{ // Snap Upwards if more than halfway between to grid units
48                         value = ( snapvalue + 1 ) * SnapToGrid;
49                 }
50         }
51         return value;
52 }
53 // Hydra : snap-to-grid end
54
55 //=============================================================
56 bool ValidSurface(){
57         if ( WaveType == WAVE_BITMAP && !gbmp.colors ) {
58                 return FALSE;
59         }
60         if ( NH  < 1 ) {
61                 return FALSE;
62         }
63         if ( NH  > MAX_ROWS ) {
64                 return FALSE;
65         }
66         if ( NV  < 1 ) {
67                 return FALSE;
68         }
69         if ( NV  > MAX_ROWS ) {
70                 return FALSE;
71         }
72         if ( Hll >= Hur ) {
73                 return FALSE;
74         }
75         if ( Vll >= Vur ) {
76                 return FALSE;
77         }
78         return TRUE;
79 }
80
81 //=============================================================
82 int MapPatches(){
83         int NH_remain;
84         int NV_remain;
85         int NH_patch;
86         int NV_patch;
87         int BrushNum = 0;
88         int i, j, k1, k2, k3;
89         int i0, j0, ii;
90         char szOops[128];
91         patchMesh_t p;
92
93         dh = ( Hur - Hll ) / NH;
94         dv = ( Vur - Vll ) / NV;
95         memset( &p,0,sizeof( patchMesh_t ) );
96
97         // Generate control points in pp array to give desired values currently
98         // in p array.
99         switch ( Plane )
100         {
101         case PLANE_XY0:
102         case PLANE_XY1:
103                 k1 = 0;
104                 k2 = 1;
105                 k3 = 2;
106                 break;
107         case PLANE_XZ0:
108         case PLANE_XZ1:
109                 k1 = 0;
110                 k2 = 2;
111                 k3 = 1;
112                 break;
113         case PLANE_YZ0:
114         case PLANE_YZ1:
115                 k1 = 1;
116                 k2 = 2;
117                 k3 = 0;
118                 break;
119         }
120         for ( i = 0; i <= NH; i++ )
121         {
122                 for ( j = 0; j <= NV; j++ )
123                 {
124                         xyz[i][j].pp[k1] = xyz[i][j].p[k1];
125                         xyz[i][j].pp[k2] = xyz[i][j].p[k2];
126                 }
127         }
128         for ( i = 0; i <= NH; i += 2 )
129         {
130                 for ( j = 0; j <= NV; j += 2 )
131                         xyz[i][j].pp[k3] = xyz[i][j].p[k3];
132         }
133         for ( i = 1; i < NH; i += 2 )
134         {
135                 for ( j = 0; j <= NV; j += 2 )
136                 {
137                         xyz[i][j].pp[k3] = ( 4 * xyz[i][j].p[k3] - xyz[i - 1][j].p[k3] - xyz[i + 1][j].p[k3] ) / 2;
138                 }
139         }
140         for ( j = 1; j < NV; j += 2 )
141         {
142                 for ( i = 0; i <= NH; i += 2 )
143                 {
144                         xyz[i][j].pp[k3] = ( 4 * xyz[i][j].p[k3] - xyz[i][j - 1].p[k3] - xyz[i][j + 1].p[k3] ) / 2;
145                 }
146         }
147         for ( i = 1; i < NH; i += 2 )
148         {
149                 for ( j = 1; j < NV; j += 2 )
150                 {
151                         xyz[i][j].pp[k3] = ( 16 * xyz[i][j].p[k3] - xyz[i - 1][j - 1].p[k3] - 2 * xyz[i][j - 1].p[k3]
152                                                                  - xyz[i + 1][j - 1].p[k3] - 2 * xyz[i - 1][j].p[k3] - 2 * xyz[i + 1][j].p[k3]
153                                                                  - xyz[i - 1][j + 1].p[k3] - 2 * xyz[i][j + 1].p[k3] - xyz[i + 1][j + 1].p[k3] ) / 4;
154                 }
155         }
156
157         NH_remain = NH + 1;
158         i0 = 0;
159         while ( NH_remain > 1 )
160         {
161                 if ( ( ( NH_remain - 1 ) % 14 ) == 0 ) {
162                         NH_patch = 15;
163                 }
164                 else if ( ( ( NH_remain - 1 ) % 12 ) == 0 ) {
165                         NH_patch = 13;
166                 }
167                 else if ( ( ( NH_remain - 1 ) % 10 ) == 0 ) {
168                         NH_patch = 11;
169                 }
170                 else if ( ( ( NH_remain - 1 ) % 8 ) == 0 ) {
171                         NH_patch = 9;
172                 }
173                 else if ( ( ( NH_remain - 1 ) % 6 ) == 0 ) {
174                         NH_patch = 7;
175                 }
176                 else if ( ( ( NH_remain - 1 ) % 4 ) == 0 ) {
177                         NH_patch = 5;
178                 }
179                 else if ( ( ( NH_remain - 1 ) % 2 ) == 0 ) {
180                         NH_patch = 3;
181                 }
182                 else if ( NH_remain > 16 ) {
183                         NH_patch = 7;
184                 }
185                 else if ( NH_remain > 4 ) {
186                         NH_patch = 5;
187                 }
188                 else{
189                         NH_patch = 3;
190                 }
191                 while ( NH_patch > 3 && ( NH_patch - 1 ) * dh > 512 )
192                         NH_patch -= 2;
193                 NH_remain -= ( NH_patch - 1 );
194                 if ( NH_remain < 0 ) {
195                         sprintf( szOops,"Oops... screwed up with NH=%d",NH );
196                         g_FuncTable.m_pfnMessageBox( NULL,szOops,"Uh oh", 0, NULL );
197                 }
198                 NV_remain = NV + 1;
199                 j0 = 0;
200                 while ( NV_remain > 1 )
201                 {
202                         if ( ( ( NV_remain - 1 ) % 14 ) == 0 ) {
203                                 NV_patch = 15;
204                         }
205                         else if ( ( ( NV_remain - 1 ) % 12 ) == 0 ) {
206                                 NV_patch = 13;
207                         }
208                         else if ( ( ( NV_remain - 1 ) % 10 ) == 0 ) {
209                                 NV_patch = 11;
210                         }
211                         else if ( ( ( NV_remain - 1 ) % 8 ) == 0 ) {
212                                 NV_patch = 9;
213                         }
214                         else if ( ( ( NV_remain - 1 ) % 6 ) == 0 ) {
215                                 NV_patch = 7;
216                         }
217                         else if ( ( ( NV_remain - 1 ) % 4 ) == 0 ) {
218                                 NV_patch = 5;
219                         }
220                         else if ( ( ( NV_remain - 1 ) % 2 ) == 0 ) {
221                                 NV_patch = 3;
222                         }
223                         else if ( NV_remain > 16 ) {
224                                 NV_patch = 7;
225                         }
226                         else if ( NV_remain > 4 ) {
227                                 NV_patch = 5;
228                         }
229                         else{
230                                 NV_patch = 3;
231                         }
232                         while ( NV_patch > 3 && ( NV_patch - 1 ) * dh > 512 )
233                                 NV_patch -= 2;
234                         NV_remain -= ( NV_patch - 1 );
235                         if ( NV_remain < 0 ) {
236                                 sprintf( szOops,"Oops... screwed up with NV=%d",NV );
237                                 g_FuncTable.m_pfnMessageBox( NULL,szOops,"Uh oh", 0, NULL );
238                         }
239
240                         p.width  = NH_patch;
241                         p.height = NV_patch;
242                         p.type   = PATCH_GENERIC;
243                         for ( i = 0; i < NH_patch; i++ )
244                         {
245                                 switch ( Plane )
246                                 {
247                                 case PLANE_XY1:
248                                 case PLANE_XZ0:
249                                 case PLANE_YZ1:
250                                         ii = i0 + NH_patch - 1 - i;
251                                         break;
252                                 default:
253                                         ii = i0 + i;
254                                 }
255                                 for ( j = 0; j < NV_patch; j++ )
256                                 {
257                                         p.ctrl[i][j].xyz[0] = (float)xyz[ii][j0 + j].pp[0];
258                                         p.ctrl[i][j].xyz[1] = (float)xyz[ii][j0 + j].pp[1];
259                                         p.ctrl[i][j].xyz[2] = (float)xyz[ii][j0 + j].pp[2];
260                                         p.ctrl[i][j].st[0]  = (float)i;
261                                         p.ctrl[i][j].st[1]  = (float)j;
262                                 }
263                         }
264                         MakePatch( &p );
265                         BrushNum++;
266                         j0 += NV_patch - 1;
267                 }
268                 i0 += NH_patch - 1;
269         }
270         return BrushNum;
271 }
272
273 //=============================================================
274 void MapBrushes(){
275         char hint[128];
276         char skip[128];
277         char sidetext[64];
278         char surftext[64];
279         char surftext2[64];
280         char surft[64];
281         float Steep;
282         vec3_t PlaneNormal,SurfNormal;
283         vec3_t t[2];
284         int i, j, k;
285         int surf;
286         bool CheckAngle;
287         BRUSH brush;
288         XYZ v[8];
289
290         strcpy( surftext,Texture[Game][0] );
291         strcpy( sidetext,( strlen( Texture[Game][1] ) ? Texture[Game][1] : Texture[Game][0] ) );
292         strcpy( surftext2,( strlen( Texture[Game][2] ) ? Texture[Game][2] : Texture[Game][0] ) );
293
294         // if surftext2 is identical to surftext, there's no need to
295         // check surface angle
296         if ( !g_strcasecmp( surftext,surftext2 ) ) {
297                 CheckAngle = FALSE;
298         }
299         else
300         {
301                 CheckAngle = TRUE;
302                 Steep = (float)cos( (double)SlantAngle / 57.2957795 );
303                 switch ( Plane )
304                 {
305                 case PLANE_XY0: PlaneNormal[0] = 0.; PlaneNormal[1] = 0.; PlaneNormal[2] = 1.; break;
306                 case PLANE_XY1: PlaneNormal[0] = 0.; PlaneNormal[1] = 0.; PlaneNormal[2] = -1.; break;
307                 case PLANE_XZ0: PlaneNormal[0] = 0.; PlaneNormal[1] = 1.; PlaneNormal[2] = 1.; break;
308                 case PLANE_XZ1: PlaneNormal[0] = 0.; PlaneNormal[1] = -1.; PlaneNormal[2] = 1.; break;
309                 case PLANE_YZ0: PlaneNormal[0] = 1.; PlaneNormal[1] = 0.; PlaneNormal[2] = 1.; break;
310                 case PLANE_YZ1: PlaneNormal[0] = -1.; PlaneNormal[1] = 0.; PlaneNormal[2] = 1.; break;
311                 }
312         }
313
314         OpenFuncGroup();
315
316         for ( i = 0; i < NH; i++ )
317         {
318                 for ( j = 0; j < NV; j++ )
319                 {
320                         if ( ( i + j ) % 2 ) {
321                                 VectorCopy( xyz[i  ][j  ].p, v[0].p );
322                                 switch ( Plane )
323                                 {
324                                 case PLANE_XY1:
325                                 case PLANE_XZ1:
326                                 case PLANE_YZ1:
327                                         VectorCopy( xyz[i + 1][j  ].p, v[1].p );
328                                         VectorCopy( xyz[i + 1][j + 1].p, v[2].p );
329                                         break;
330                                 default:
331                                         VectorCopy( xyz[i + 1][j + 1].p, v[1].p );
332                                         VectorCopy( xyz[i + 1][j  ].p, v[2].p );
333                                 }
334                         }
335                         else
336                         {
337                                 VectorCopy( xyz[i  ][j  ].p, v[0].p );
338                                 switch ( Plane )
339                                 {
340                                 case PLANE_XY1:
341                                 case PLANE_XZ1:
342                                 case PLANE_YZ1:
343                                         VectorCopy( xyz[i + 1][j  ].p, v[1].p );
344                                         VectorCopy( xyz[i  ][j + 1].p, v[2].p );
345                                         break;
346                                 default:
347                                         VectorCopy( xyz[i  ][j + 1].p, v[1].p );
348                                         VectorCopy( xyz[i + 1][j  ].p, v[2].p );
349                                 }
350                         }
351                         VectorCopy( v[0].p,v[3].p );
352                         VectorCopy( v[1].p,v[4].p );
353                         VectorCopy( v[2].p,v[5].p );
354                         switch ( Plane )
355                         {
356                         case PLANE_XZ0:
357                         case PLANE_XZ1:
358                                 v[0].p[1] = backface;
359                                 v[1].p[1] = backface;
360                                 v[2].p[1] = backface;
361                                 break;
362                         case PLANE_YZ0:
363                         case PLANE_YZ1:
364                                 v[3].p[0] = backface;
365                                 v[4].p[0] = backface;
366                                 v[5].p[0] = backface;
367                                 break;
368                         default:
369                                 v[3].p[2] = backface;
370                                 v[4].p[2] = backface;
371                                 v[5].p[2] = backface;
372                         }
373
374                         brush.Number   = i * NV * 2 + j * 2;
375                         brush.NumFaces = 5;
376                         XYZtoV( &v[0],&brush.face[0].v[0] );
377                         XYZtoV( &v[3],&brush.face[0].v[1] );
378                         XYZtoV( &v[4],&brush.face[0].v[2] );
379                         strcpy( brush.face[0].texture,
380                                         ( strlen( Texture[Game][1] ) ? Texture[Game][1] : Texture[Game][0] ) );
381                         brush.face[0].Shift[0] = (float)TexOffset[0];
382                         brush.face[0].Shift[1] = (float)TexOffset[1];
383                         brush.face[0].Rotate   = 0.;
384                         brush.face[0].Scale[0] = (float)TexScale[0];
385                         brush.face[0].Scale[1] = (float)TexScale[1];
386                         brush.face[0].Contents = contents;
387                         brush.face[0].Surface  = surface[1];
388                         brush.face[0].Value    = 0;
389
390                         XYZtoV( &v[1],&brush.face[1].v[0] );
391                         XYZtoV( &v[4],&brush.face[1].v[1] );
392                         XYZtoV( &v[5],&brush.face[1].v[2] );
393                         strcpy( brush.face[1].texture,
394                                         ( strlen( Texture[Game][1] ) ? Texture[Game][1] : Texture[Game][0] ) );
395                         brush.face[1].Shift[0] = (float)TexOffset[0];
396                         brush.face[1].Shift[1] = (float)TexOffset[1];
397                         brush.face[1].Rotate   = 0.;
398                         brush.face[1].Scale[0] = (float)TexScale[0];
399                         brush.face[1].Scale[1] = (float)TexScale[1];
400                         brush.face[1].Contents = contents;
401                         brush.face[1].Surface  = surface[1];
402                         brush.face[1].Value    = 0;
403
404                         XYZtoV( &v[2],&brush.face[2].v[0] );
405                         XYZtoV( &v[5],&brush.face[2].v[1] );
406                         XYZtoV( &v[3],&brush.face[2].v[2] );
407                         strcpy( brush.face[2].texture,
408                                         ( strlen( Texture[Game][1] ) ? Texture[Game][1] : Texture[Game][0] ) );
409                         brush.face[2].Shift[0] = (float)TexOffset[0];
410                         brush.face[2].Shift[1] = (float)TexOffset[1];
411                         brush.face[2].Rotate   = 0.;
412                         brush.face[2].Scale[0] = (float)TexScale[0];
413                         brush.face[2].Scale[1] = (float)TexScale[1];
414                         brush.face[2].Contents = contents;
415                         brush.face[2].Surface  = surface[1];
416                         brush.face[2].Value    = 0;
417
418                         if ( CheckAngle && ( Plane == PLANE_XZ0 || Plane == PLANE_XZ1 ) ) {
419                                 XYZVectorSubtract( v[4].p,v[3].p,t[0] );
420                                 XYZVectorSubtract( v[5].p,v[4].p,t[1] );
421                                 CrossProduct( t[0],t[1],SurfNormal );
422                                 VectorNormalize( SurfNormal,SurfNormal );
423                                 if ( DotProduct( SurfNormal,PlaneNormal ) < Steep ) {
424                                         strcpy( surft,surftext2 );
425                                         surf = surface[2];
426                                 }
427                                 else
428                                 {
429                                         strcpy( surft,surftext );
430                                         surf = surface[0];
431                                 }
432                         }
433                         else
434                         {
435                                 strcpy( surft,surftext );
436                                 surf = surface[0];
437                         }
438
439                         XYZtoV( &v[3],&brush.face[3].v[0] );
440                         XYZtoV( &v[5],&brush.face[3].v[1] );
441                         XYZtoV( &v[4],&brush.face[3].v[2] );
442                         strcpy( brush.face[3].texture,
443                                         ( Plane == PLANE_XZ0 || Plane == PLANE_XZ1 ? surft : sidetext ) );
444                         brush.face[3].Shift[0] = (float)TexOffset[0];
445                         brush.face[3].Shift[1] = (float)TexOffset[1];
446                         brush.face[3].Rotate   = 0.;
447                         brush.face[3].Scale[0] = (float)TexScale[0];
448                         brush.face[3].Scale[1] = (float)TexScale[1];
449                         brush.face[3].Contents = contents;
450                         brush.face[3].Surface  = ( Plane == PLANE_XZ0 || Plane == PLANE_XZ1 ? surf : surface[1] );
451                         brush.face[3].Value    = ( Plane == PLANE_XZ0 || Plane == PLANE_XZ1 ? ArghRad2 : 0 );
452
453                         if ( CheckAngle && Plane != PLANE_XZ0 && Plane != PLANE_XZ1 ) {
454                                 XYZVectorSubtract( v[2].p,v[0].p,t[0] );
455                                 XYZVectorSubtract( v[1].p,v[2].p,t[1] );
456                                 CrossProduct( t[0],t[1],SurfNormal );
457                                 VectorNormalize( SurfNormal,SurfNormal );
458                                 if ( DotProduct( SurfNormal,PlaneNormal ) < Steep ) {
459                                         strcpy( surft,surftext2 );
460                                         surf = surface[2];
461                                 }
462                                 else
463                                 {
464                                         strcpy( surft,surftext );
465                                         surf = surface[0];
466                                 }
467                         }
468                         else
469                         {
470                                 strcpy( surft,surftext );
471                                 surf = surface[0];
472                         }
473
474                         XYZtoV( &v[0],&brush.face[4].v[0] );
475                         XYZtoV( &v[1],&brush.face[4].v[1] );
476                         XYZtoV( &v[2],&brush.face[4].v[2] );
477                         strcpy( brush.face[4].texture,
478                                         ( Plane == PLANE_XZ0 || Plane == PLANE_XZ1 ? sidetext : surft ) );
479                         brush.face[4].Shift[0] = (float)TexOffset[0];
480                         brush.face[4].Shift[1] = (float)TexOffset[1];
481                         brush.face[4].Rotate   = 0.;
482                         brush.face[4].Scale[0] = (float)TexScale[0];
483                         brush.face[4].Scale[1] = (float)TexScale[1];
484                         brush.face[4].Contents = contents;
485                         brush.face[4].Surface  = ( Plane == PLANE_XZ0 || Plane == PLANE_XZ1 ? surface[1] : surf );
486                         brush.face[4].Value    = ( Plane == PLANE_XZ0 || Plane == PLANE_XZ1 ? 0 : ArghRad2 );
487
488                         MakeBrush( &brush );
489                         if ( ( i + j ) % 2 ) {
490                                 VectorCopy( xyz[i  ][j + 1].p,v[0].p );
491                                 switch ( Plane )
492                                 {
493                                 case PLANE_XY1:
494                                 case PLANE_XZ1:
495                                 case PLANE_YZ1:
496                                         VectorCopy( xyz[i  ][j  ].p,v[1].p );
497                                         VectorCopy( xyz[i + 1][j + 1].p,v[2].p );
498                                         break;
499                                 default:
500                                         VectorCopy( xyz[i + 1][j + 1].p,v[1].p );
501                                         VectorCopy( xyz[i  ][j  ].p,v[2].p );
502                                 }
503                         }
504                         else
505                         {
506                                 VectorCopy( xyz[i  ][j + 1].p,v[0].p );
507                                 switch ( Plane )
508                                 {
509                                 case PLANE_XY1:
510                                 case PLANE_XZ1:
511                                 case PLANE_YZ1:
512                                         VectorCopy( xyz[i + 1][j  ].p,v[1].p );
513                                         VectorCopy( xyz[i + 1][j + 1].p,v[2].p );
514                                         break;
515                                 default:
516                                         VectorCopy( xyz[i + 1][j + 1].p,v[1].p );
517                                         VectorCopy( xyz[i + 1][j  ].p,v[2].p );
518                                 }
519                         }
520                         VectorCopy( v[0].p,v[3].p );
521                         VectorCopy( v[1].p,v[4].p );
522                         VectorCopy( v[2].p,v[5].p );
523                         switch ( Plane )
524                         {
525                         case PLANE_XZ0:
526                         case PLANE_XZ1:
527                                 v[0].p[1] = backface;
528                                 v[1].p[1] = backface;
529                                 v[2].p[1] = backface;
530                                 break;
531                         case PLANE_YZ0:
532                         case PLANE_YZ1:
533                                 v[3].p[0] = backface;
534                                 v[4].p[0] = backface;
535                                 v[5].p[0] = backface;
536                                 break;
537                         default:
538                                 v[3].p[2] = backface;
539                                 v[4].p[2] = backface;
540                                 v[5].p[2] = backface;
541                         }
542                         brush.Number   = i * NV * 2 + j * 2 + 1;
543                         brush.NumFaces = 5;
544                         XYZtoV( &v[0],&brush.face[0].v[0] );
545                         XYZtoV( &v[3],&brush.face[0].v[1] );
546                         XYZtoV( &v[4],&brush.face[0].v[2] );
547                         strcpy( brush.face[0].texture,
548                                         ( strlen( Texture[Game][1] ) ? Texture[Game][1] : Texture[Game][0] ) );
549                         brush.face[0].Shift[0] = (float)TexOffset[0];
550                         brush.face[0].Shift[1] = (float)TexOffset[1];
551                         brush.face[0].Rotate   = 0.;
552                         brush.face[0].Scale[0] = (float)TexScale[0];
553                         brush.face[0].Scale[1] = (float)TexScale[1];
554                         brush.face[0].Contents = contents;
555                         brush.face[0].Surface  = surface[1];
556                         brush.face[0].Value    = 0;
557
558                         XYZtoV( &v[1],&brush.face[1].v[0] );
559                         XYZtoV( &v[4],&brush.face[1].v[1] );
560                         XYZtoV( &v[5],&brush.face[1].v[2] );
561                         strcpy( brush.face[1].texture,
562                                         ( strlen( Texture[Game][1] ) ? Texture[Game][1] : Texture[Game][0] ) );
563                         brush.face[1].Shift[0] = (float)TexOffset[0];
564                         brush.face[1].Shift[1] = (float)TexOffset[1];
565                         brush.face[1].Rotate   = 0.;
566                         brush.face[1].Scale[0] = (float)TexScale[0];
567                         brush.face[1].Scale[1] = (float)TexScale[1];
568                         brush.face[1].Contents = contents;
569                         brush.face[1].Surface  = surface[1];
570                         brush.face[1].Value    = 0;
571
572                         XYZtoV( &v[2],&brush.face[2].v[0] );
573                         XYZtoV( &v[5],&brush.face[2].v[1] );
574                         XYZtoV( &v[3],&brush.face[2].v[2] );
575                         strcpy( brush.face[2].texture,
576                                         ( strlen( Texture[Game][1] ) ? Texture[Game][1] : Texture[Game][0] ) );
577                         brush.face[2].Shift[0] = (float)TexOffset[0];
578                         brush.face[2].Shift[1] = (float)TexOffset[1];
579                         brush.face[2].Rotate   = 0.;
580                         brush.face[2].Scale[0] = (float)TexScale[0];
581                         brush.face[2].Scale[1] = (float)TexScale[1];
582                         brush.face[2].Contents = contents;
583                         brush.face[2].Surface  = surface[1];
584                         brush.face[2].Value    = 0;
585
586                         if ( CheckAngle && ( Plane == PLANE_XZ0 || Plane == PLANE_XZ1 ) ) {
587                                 XYZVectorSubtract( v[4].p,v[3].p,t[0] );
588                                 XYZVectorSubtract( v[5].p,v[4].p,t[1] );
589                                 CrossProduct( t[0],t[1],SurfNormal );
590                                 VectorNormalize( SurfNormal,SurfNormal );
591                                 if ( DotProduct( SurfNormal,PlaneNormal ) < Steep ) {
592                                         strcpy( surft,surftext2 );
593                                         surf = surface[2];
594                                 }
595                                 else
596                                 {
597                                         strcpy( surft,surftext );
598                                         surf = surface[0];
599                                 }
600                         }
601                         else
602                         {
603                                 strcpy( surft,surftext );
604                                 surf = surface[0];
605                         }
606                         XYZtoV( &v[3],&brush.face[3].v[0] );
607                         XYZtoV( &v[5],&brush.face[3].v[1] );
608                         XYZtoV( &v[4],&brush.face[3].v[2] );
609                         strcpy( brush.face[3].texture,
610                                         ( Plane == PLANE_XZ0 || Plane == PLANE_XZ1 ? surft : sidetext ) );
611                         brush.face[3].Shift[0] = (float)TexOffset[0];
612                         brush.face[3].Shift[1] = (float)TexOffset[1];
613                         brush.face[3].Rotate   = 0.;
614                         brush.face[3].Scale[0] = (float)TexScale[0];
615                         brush.face[3].Scale[1] = (float)TexScale[1];
616                         brush.face[3].Contents = contents;
617                         brush.face[3].Surface  = ( Plane == PLANE_XZ0 || Plane == PLANE_XZ1 ? surf : surface[1] );
618                         brush.face[3].Value    = ( Plane == PLANE_XZ0 || Plane == PLANE_XZ1 ? ArghRad2 : 0 );
619
620                         if ( CheckAngle && Plane != PLANE_XZ0 && Plane != PLANE_XZ1 ) {
621                                 XYZVectorSubtract( v[2].p,v[0].p,t[0] );
622                                 XYZVectorSubtract( v[1].p,v[2].p,t[1] );
623                                 CrossProduct( t[0],t[1],SurfNormal );
624                                 VectorNormalize( SurfNormal,SurfNormal );
625                                 if ( DotProduct( SurfNormal,PlaneNormal ) < Steep ) {
626                                         strcpy( surft,surftext2 );
627                                         surf = surface[2];
628                                 }
629                                 else
630                                 {
631                                         strcpy( surft,surftext );
632                                         surf = surface[0];
633                                 }
634                         }
635                         else
636                         {
637                                 strcpy( surft,surftext );
638                                 surf = surface[0];
639                         }
640                         XYZtoV( &v[0],&brush.face[4].v[0] );
641                         XYZtoV( &v[1],&brush.face[4].v[1] );
642                         XYZtoV( &v[2],&brush.face[4].v[2] );
643                         strcpy( brush.face[4].texture,
644                                         ( Plane == PLANE_XZ0 || Plane == PLANE_XZ1 ? sidetext : surft ) );
645                         brush.face[4].Shift[0] = (float)TexOffset[0];
646                         brush.face[4].Shift[1] = (float)TexOffset[1];
647                         brush.face[4].Rotate   = 0.;
648                         brush.face[4].Scale[0] = (float)TexScale[0];
649                         brush.face[4].Scale[1] = (float)TexScale[1];
650                         brush.face[4].Contents = contents;
651                         brush.face[4].Surface  = ( Plane == PLANE_XZ0 || Plane == PLANE_XZ1 ? surface[1] : surf );
652                         brush.face[4].Value    = ( Plane == PLANE_XZ0 || Plane == PLANE_XZ1 ? 0 : ArghRad2 );
653
654                         MakeBrush( &brush );
655                 }
656         }
657         CloseFuncGroup();
658
659         if ( AddHints || GimpHints ) {
660                 int detail, i1, j1, N;
661                 double front;
662
663                 switch ( Game )
664                 {
665                 case HALFLIFE:
666                         strcpy( hint,"HINT" );
667                         strcpy( skip,"HINT" );
668                         break;
669                 case SIN:
670                         strcpy( hint,"generic/misc/hint" );
671                         strcpy( skip,"generic/misc/skip" );
672                         break;
673                 case HERETIC2:
674                         strcpy( hint,"general/hint" );
675                         strcpy( skip,"general/hint" ); // Heretic2 doesn't have a skip texture
676                         break;
677                 case KINGPIN:
678                         strcpy( hint,"common/0_hint" );
679                         strcpy( skip,"common/0_skip" );
680                         break;
681                 case GENESIS3D:
682                         strcpy( hint,"hint" );
683                         strcpy( skip,"hint" );
684                         break;
685                 case QUAKE3:
686                         strcpy( hint,"textures/common/hint" );
687                         strcpy( skip,"textures/common/skip" );
688                         break;
689                 default:
690                         strcpy( hint,"e1u1/hint" );
691                         strcpy( skip,"e1u1/skip" );
692                 }
693
694                 OpenFuncGroup();
695
696                 if ( AddHints == 1 ) {
697                         detail = CONTENTS_DETAIL;
698                         N = 0;
699                         for ( i = 0; i < NH; i++ )
700                         {
701                                 i1 = i + 1;
702
703                                 for ( j = 0; j < NV; j++ )
704                                 {
705
706                                         // For detail hint brushes, no need to use a hint brush over
707                                         // EVERY grid square... it would be redundant. Instead use
708                                         // a checkerboard pattern
709                                         if ( ( i + j ) % 2 ) {
710                                                 continue;
711                                         }
712
713                                         j1 = j + 1;
714
715                                         VectorCopy( xyz[i  ][j  ].p, v[0].p );
716                                         switch ( Plane )
717                                         {
718                                         case PLANE_XY1:
719                                         case PLANE_XZ1:
720                                         case PLANE_YZ1:
721                                                 VectorCopy( xyz[i1][j ].p, v[1].p );
722                                                 VectorCopy( xyz[i1][j1].p, v[2].p );
723                                                 VectorCopy( xyz[i ][j1].p, v[3].p );
724                                                 break;
725                                         default:
726                                                 VectorCopy( xyz[i ][j1].p, v[1].p );
727                                                 VectorCopy( xyz[i1][j1].p, v[2].p );
728                                                 VectorCopy( xyz[i1][j ].p, v[3].p );
729                                         }
730
731                                         VectorCopy( v[0].p,v[4].p );
732                                         VectorCopy( v[1].p,v[5].p );
733                                         VectorCopy( v[2].p,v[6].p );
734                                         VectorCopy( v[3].p,v[7].p );
735
736                                         switch ( Plane )
737                                         {
738                                         case PLANE_XY1:
739                                                 front  = LessThan( zmin,32. );
740                                                 v[4].p[2] = backface;
741                                                 v[5].p[2] = backface;
742                                                 v[6].p[2] = backface;
743                                                 v[7].p[2] = backface;
744                                                 break;
745                                         case PLANE_XZ0:
746                                                 front  = MoreThan( ymax,32. );
747                                                 v[0].p[1] = backface;
748                                                 v[1].p[1] = backface;
749                                                 v[2].p[1] = backface;
750                                                 v[3].p[1] = backface;
751                                                 break;
752                                         case PLANE_XZ1:
753                                                 front  = LessThan( ymin,32. );
754                                                 v[0].p[1] = backface;
755                                                 v[1].p[1] = backface;
756                                                 v[2].p[1] = backface;
757                                                 v[3].p[1] = backface;
758                                                 break;
759                                         case PLANE_YZ0:
760                                                 front  = MoreThan( xmax,32. );
761                                                 v[4].p[0] = backface;
762                                                 v[5].p[0] = backface;
763                                                 v[6].p[0] = backface;
764                                                 v[7].p[0] = backface;
765                                                 break;
766                                         case PLANE_YZ1:
767                                                 front  = LessThan( xmin,32. );
768                                                 v[4].p[0] = backface;
769                                                 v[5].p[0] = backface;
770                                                 v[6].p[0] = backface;
771                                                 v[7].p[0] = backface;
772                                                 break;
773                                         default:
774                                                 front  = MoreThan( zmax,32. );
775                                                 v[4].p[2] = backface;
776                                                 v[5].p[2] = backface;
777                                                 v[6].p[2] = backface;
778                                                 v[7].p[2] = backface;
779                                         }
780
781                                         switch ( Plane )
782                                         {
783                                         case PLANE_XZ0:
784                                         case PLANE_XZ1:
785                                                 v[4].p[1] = front;
786                                                 v[5].p[1] = v[4].p[1];
787                                                 v[6].p[1] = v[4].p[1];
788                                                 v[7].p[1] = v[4].p[1];
789                                                 break;
790                                         case PLANE_YZ0:
791                                         case PLANE_YZ1:
792                                                 v[0].p[0] = front;
793                                                 v[1].p[0] = v[0].p[0];
794                                                 v[2].p[0] = v[0].p[0];
795                                                 v[3].p[0] = v[0].p[0];
796                                                 break;
797                                         default:
798                                                 v[0].p[2] = front;
799                                                 v[1].p[2] = v[0].p[2];
800                                                 v[2].p[2] = v[0].p[2];
801                                                 v[3].p[2] = v[0].p[2];
802                                         }
803
804                                         brush.NumFaces = 6;
805                                         brush.Number   = N;
806                                         XYZtoV( &v[0],&brush.face[0].v[0] );
807                                         XYZtoV( &v[1],&brush.face[0].v[1] );
808                                         XYZtoV( &v[2],&brush.face[0].v[2] );
809                                         strcpy( brush.face[0].texture,skip );
810                                         brush.face[0].Shift[0] = 0.;
811                                         brush.face[0].Shift[1] = 0.;
812                                         brush.face[0].Rotate   = 0.;
813                                         brush.face[0].Scale[0] = 1.;
814                                         brush.face[0].Scale[1] = 1.;
815                                         brush.face[0].Contents = detail;
816                                         brush.face[0].Surface  = SURF_SKIP;
817                                         brush.face[0].Value    = 0;
818
819                                         XYZtoV( &v[4],&brush.face[1].v[0] );
820                                         XYZtoV( &v[7],&brush.face[1].v[1] );
821                                         XYZtoV( &v[6],&brush.face[1].v[2] );
822                                         strcpy( brush.face[1].texture,skip );
823                                         brush.face[1].Shift[0] = 0.;
824                                         brush.face[1].Shift[1] = 0.;
825                                         brush.face[1].Rotate   = 0.;
826                                         brush.face[1].Scale[0] = 1.;
827                                         brush.face[1].Scale[1] = 1.;
828                                         brush.face[1].Contents = detail;
829                                         brush.face[1].Surface  = SURF_SKIP;
830                                         brush.face[1].Value    = 0;
831
832                                         XYZtoV( &v[0],&brush.face[2].v[0] );
833                                         XYZtoV( &v[4],&brush.face[2].v[1] );
834                                         XYZtoV( &v[5],&brush.face[2].v[2] );
835                                         strcpy( brush.face[2].texture,hint );
836                                         brush.face[2].Shift[0] = 0.;
837                                         brush.face[2].Shift[1] = 0.;
838                                         brush.face[2].Rotate   = 0.;
839                                         brush.face[2].Scale[0] = 1.;
840                                         brush.face[2].Scale[1] = 1.;
841                                         brush.face[2].Contents = detail;
842                                         brush.face[2].Surface  = SURF_HINT;
843                                         brush.face[2].Value    = 0;
844
845                                         XYZtoV( &v[1],&brush.face[3].v[0] );
846                                         XYZtoV( &v[5],&brush.face[3].v[1] );
847                                         XYZtoV( &v[6],&brush.face[3].v[2] );
848                                         strcpy( brush.face[3].texture,hint );
849                                         brush.face[3].Shift[0] = 0.;
850                                         brush.face[3].Shift[1] = 0.;
851                                         brush.face[3].Rotate   = 0.;
852                                         brush.face[3].Scale[0] = 1.;
853                                         brush.face[3].Scale[1] = 1.;
854                                         brush.face[3].Contents = detail;
855                                         brush.face[3].Surface  = SURF_HINT;
856                                         brush.face[3].Value    = 0;
857
858                                         XYZtoV( &v[2],&brush.face[4].v[0] );
859                                         XYZtoV( &v[6],&brush.face[4].v[1] );
860                                         XYZtoV( &v[7],&brush.face[4].v[2] );
861                                         strcpy( brush.face[4].texture,hint );
862                                         brush.face[4].Shift[0] = 0.;
863                                         brush.face[4].Shift[1] = 0.;
864                                         brush.face[4].Rotate   = 0.;
865                                         brush.face[4].Scale[0] = 1.;
866                                         brush.face[4].Scale[1] = 1.;
867                                         brush.face[4].Contents = detail;
868                                         brush.face[4].Surface  = SURF_HINT;
869                                         brush.face[4].Value    = 0;
870
871                                         XYZtoV( &v[3],&brush.face[5].v[0] );
872                                         XYZtoV( &v[7],&brush.face[5].v[1] );
873                                         XYZtoV( &v[4],&brush.face[5].v[2] );
874                                         strcpy( brush.face[5].texture,hint );
875                                         brush.face[5].Shift[0] = 0.;
876                                         brush.face[5].Shift[1] = 0.;
877                                         brush.face[5].Rotate   = 0.;
878                                         brush.face[5].Scale[0] = 1.;
879                                         brush.face[5].Scale[1] = 1.;
880                                         brush.face[5].Contents = detail;
881                                         brush.face[5].Surface  = SURF_HINT;
882                                         brush.face[5].Value    = 0;
883
884                                         MakeBrush( &brush );
885                                         N++;
886                                 }
887                         }
888                 }
889                 if ( GimpHints ) {
890                         N = 0;
891                         // these brush parameters never change
892                         brush.NumFaces = 5;
893                         for ( i = 0; i < 6; i++ )
894                         {
895                                 strcpy( brush.face[i].texture,hint );
896                                 brush.face[i].Shift[0] = 0.;
897                                 brush.face[i].Shift[1] = 0.;
898                                 brush.face[i].Rotate   = 0.;
899                                 brush.face[i].Scale[0] = 1.;
900                                 brush.face[i].Scale[1] = 1.;
901                                 brush.face[i].Contents = 0;
902                                 brush.face[i].Surface  = SURF_HINT;
903                                 brush.face[i].Value    = 0;
904                         }
905                         for ( i = 0; i < NH; i++ )
906                         {
907                                 for ( j = 0; j < NV; j++ )
908                                 {
909                                         for ( k = 0; k < 2; k++ )
910                                         {
911                                                 if ( k == 0 ) {
912                                                         if ( ( i + j ) % 2 ) {
913                                                                 VectorCopy( xyz[i  ][j  ].p, v[0].p );
914                                                                 switch ( Plane )
915                                                                 {
916                                                                 case PLANE_XY1:
917                                                                 case PLANE_XZ1:
918                                                                 case PLANE_YZ1:
919                                                                         VectorCopy( xyz[i + 1][j  ].p, v[1].p );
920                                                                         VectorCopy( xyz[i + 1][j + 1].p, v[2].p );
921                                                                         break;
922                                                                 default:
923                                                                         VectorCopy( xyz[i + 1][j + 1].p, v[1].p );
924                                                                         VectorCopy( xyz[i + 1][j  ].p, v[2].p );
925                                                                 }
926                                                         }
927                                                         else
928                                                         {
929                                                                 VectorCopy( xyz[i  ][j  ].p, v[0].p );
930                                                                 switch ( Plane )
931                                                                 {
932                                                                 case PLANE_XY1:
933                                                                 case PLANE_XZ1:
934                                                                 case PLANE_YZ1:
935                                                                         VectorCopy( xyz[i + 1][j  ].p, v[1].p );
936                                                                         VectorCopy( xyz[i  ][j + 1].p, v[2].p );
937                                                                         break;
938                                                                 default:
939                                                                         VectorCopy( xyz[i  ][j + 1].p, v[1].p );
940                                                                         VectorCopy( xyz[i + 1][j  ].p, v[2].p );
941                                                                 }
942                                                         }
943                                                 }
944                                                 else
945                                                 {
946                                                         if ( ( i + j ) % 2 ) {
947                                                                 VectorCopy( xyz[i  ][j + 1].p,v[0].p );
948                                                                 switch ( Plane )
949                                                                 {
950                                                                 case PLANE_XY1:
951                                                                 case PLANE_XZ1:
952                                                                 case PLANE_YZ1:
953                                                                         VectorCopy( xyz[i  ][j  ].p,v[1].p );
954                                                                         VectorCopy( xyz[i + 1][j + 1].p,v[2].p );
955                                                                         break;
956                                                                 default:
957                                                                         VectorCopy( xyz[i + 1][j + 1].p,v[1].p );
958                                                                         VectorCopy( xyz[i  ][j  ].p,v[2].p );
959                                                                 }
960                                                         }
961                                                         else
962                                                         {
963                                                                 VectorCopy( xyz[i  ][j + 1].p,v[0].p );
964                                                                 switch ( Plane )
965                                                                 {
966                                                                 case PLANE_XY1:
967                                                                 case PLANE_XZ1:
968                                                                 case PLANE_YZ1:
969                                                                         VectorCopy( xyz[i + 1][j  ].p,v[1].p );
970                                                                         VectorCopy( xyz[i + 1][j + 1].p,v[2].p );
971                                                                         break;
972                                                                 default:
973                                                                         VectorCopy( xyz[i + 1][j + 1].p,v[1].p );
974                                                                         VectorCopy( xyz[i + 1][j  ].p,v[2].p );
975                                                                 }
976                                                         }
977                                                 }
978                                                 VectorCopy( v[0].p,v[3].p );
979                                                 VectorCopy( v[1].p,v[4].p );
980                                                 VectorCopy( v[2].p,v[5].p );
981                                                 switch ( Plane )
982                                                 {
983                                                 case PLANE_XY0:
984                                                         v[0].p[2] += HINT_OFFSET;
985                                                         v[1].p[2] += HINT_OFFSET;
986                                                         v[2].p[2] += HINT_OFFSET;
987 //              v[3].p[2] = backface;
988 //              v[4].p[2] = backface;
989 //              v[5].p[2] = backface;
990                                                         break;
991                                                 case PLANE_XY1:
992                                                         v[0].p[2] -= HINT_OFFSET;
993                                                         v[1].p[2] -= HINT_OFFSET;
994                                                         v[2].p[2] -= HINT_OFFSET;
995 //              v[3].p[2] = backface;
996 //              v[4].p[2] = backface;
997 //              v[5].p[2] = backface;
998                                                         break;
999                                                 case PLANE_XZ0:
1000 //              v[0].p[1] = backface;
1001 //              v[1].p[1] = backface;
1002 //              v[2].p[1] = backface;
1003                                                         v[3].p[1] += HINT_OFFSET;
1004                                                         v[4].p[1] += HINT_OFFSET;
1005                                                         v[5].p[1] += HINT_OFFSET;
1006                                                         break;
1007                                                 case PLANE_XZ1:
1008 //              v[0].p[1] = backface;
1009 //              v[1].p[1] = backface;
1010 //              v[2].p[1] = backface;
1011                                                         v[3].p[1] -= HINT_OFFSET;
1012                                                         v[4].p[1] -= HINT_OFFSET;
1013                                                         v[5].p[1] -= HINT_OFFSET;
1014                                                         break;
1015                                                 case PLANE_YZ0:
1016                                                         v[0].p[0] += HINT_OFFSET;
1017                                                         v[1].p[0] += HINT_OFFSET;
1018                                                         v[2].p[0] += HINT_OFFSET;
1019 //              v[3].p[0] = backface;
1020 //              v[4].p[0] = backface;
1021 //              v[5].p[0] = backface;
1022                                                         break;
1023                                                 case PLANE_YZ1:
1024                                                         v[0].p[0] -= HINT_OFFSET;
1025                                                         v[1].p[0] -= HINT_OFFSET;
1026                                                         v[2].p[0] -= HINT_OFFSET;
1027 //              v[3].p[0] = backface;
1028 //              v[4].p[0] = backface;
1029 //              v[5].p[0] = backface;
1030                                                         break;
1031                                                 }
1032                                                 brush.Number   = N;
1033                                                 XYZtoV( &v[0],&brush.face[0].v[0] );
1034                                                 XYZtoV( &v[3],&brush.face[0].v[1] );
1035                                                 XYZtoV( &v[4],&brush.face[0].v[2] );
1036
1037                                                 XYZtoV( &v[1],&brush.face[1].v[0] );
1038                                                 XYZtoV( &v[4],&brush.face[1].v[1] );
1039                                                 XYZtoV( &v[5],&brush.face[1].v[2] );
1040
1041                                                 XYZtoV( &v[2],&brush.face[2].v[0] );
1042                                                 XYZtoV( &v[5],&brush.face[2].v[1] );
1043                                                 XYZtoV( &v[3],&brush.face[2].v[2] );
1044
1045                                                 XYZtoV( &v[3],&brush.face[3].v[0] );
1046                                                 XYZtoV( &v[5],&brush.face[3].v[1] );
1047                                                 XYZtoV( &v[4],&brush.face[3].v[2] );
1048
1049                                                 XYZtoV( &v[0],&brush.face[4].v[0] );
1050                                                 XYZtoV( &v[1],&brush.face[4].v[1] );
1051                                                 XYZtoV( &v[2],&brush.face[4].v[2] );
1052
1053                                                 MakeBrush( &brush );
1054                                                 N++;
1055                                         }
1056                                 }
1057                         }
1058                 } // endif AddHints==1
1059                 CloseFuncGroup();
1060         }
1061
1062 } // end MapBrushes
1063
1064 //=============================================================
1065 void GenerateMap(){
1066         extern void MapOut( int,int,NODE *,TRI * );
1067         extern bool SingleBrushSelected;
1068         int ntri;
1069
1070         if ( !ValidSurface() ) {
1071                 return;
1072         }
1073         /*
1074            ghCursorCurrent = LoadCursor(NULL,IDC_WAIT);
1075            SetCursor(ghCursorCurrent);
1076          */
1077         if ( SingleBrushSelected ) {
1078                 g_FuncTable.m_pfnDeleteSelection();
1079         }
1080
1081         GenerateXYZ();
1082         ntri = NH * NV * 2;
1083
1084         if ( Game == QUAKE3 && UsePatches != 0 ) {
1085                 MapPatches();
1086         }
1087
1088         if ( Decimate > 0 && ( Game != QUAKE3 || UsePatches == 0 ) ) {
1089                 MapOut( gNumNodes,gNumTris,gNode,gTri );
1090                 /*
1091                    ghCursorCurrent = ghCursorDefault;
1092                    SetCursor(ghCursorCurrent);
1093                  */
1094                 return;
1095         }
1096
1097         contents = 0;
1098         // HL doesn't have detail property
1099         if ( ( Game != HALFLIFE ) && UseDetail ) {
1100                 contents += CONTENTS_DETAIL;
1101         }
1102         // HL and Q3 don't have ladder property
1103         if ( ( Game != HALFLIFE && Game != QUAKE3 ) && UseLadder ) {
1104                 contents += CONTENTS_LADDER;
1105         }
1106         // Genesis requires solid property to be set explicitly
1107         if ( Game == GENESIS3D ) {
1108                 contents |= CONTENTS_SOLID;
1109         }
1110         // Heretic 2 uses different sounds (in surface props) for different texture types
1111         if ( Game == HERETIC2 ) {
1112                 surface[0] = GetDefSurfaceProps( Texture[Game][0] );
1113                 surface[1] = GetDefSurfaceProps( Texture[Game][1] );
1114                 surface[2] = GetDefSurfaceProps( Texture[Game][2] );
1115         }
1116         else
1117         {
1118                 surface[0] = 0;
1119                 surface[1] = 0;
1120                 surface[2] = 0;
1121         }
1122         if ( Game != QUAKE3 || UsePatches == 0 ) {
1123                 MapBrushes();
1124         }
1125
1126         /*
1127            ghCursorCurrent = ghCursorDefault;
1128            SetCursor(ghCursorCurrent);
1129          */
1130 }
1131
1132 //=============================================================
1133 void GenerateXYZ(){
1134         extern void MakeDecimatedMap( int *, int *, NODE * *, TRI * * );
1135         double zl, zu;
1136         double wh, wv;
1137         int NHalfcycles;
1138         double a,v,h,ha,va;
1139         double delta, dr, rate;
1140         double range, maxrange;
1141         double r;
1142         int i, j, k, N;
1143         int i0, i1, j0, j1;
1144         int ii, jj;
1145
1146 //  FILE *f;
1147 //  char CSV[64];
1148
1149         if ( !ValidSurface() ) {
1150                 return;
1151         }
1152
1153         srand( 1 );
1154         srand( RandomSeed );
1155
1156         dh = ( Hur - Hll ) / NH;
1157         dv = ( Vur - Vll ) / NV;
1158
1159         // H & V
1160         for ( i = 0; i <= NH; i++ )
1161         {
1162                 for ( j = 0; j <= NV; j++ )
1163                 {
1164                         switch ( Plane )
1165                         {
1166                         case PLANE_XZ0:
1167                         case PLANE_XZ1:
1168                                 xyz[i][j].p[0] = Hll + i * dh;
1169                                 xyz[i][j].p[2] = Vll + j * dv;
1170                                 break;
1171                         case PLANE_YZ0:
1172                         case PLANE_YZ1:
1173                                 xyz[i][j].p[1] = Hll + i * dh;
1174                                 xyz[i][j].p[2] = Vll + j * dv;
1175                                 break;
1176                         default:
1177                                 xyz[i][j].p[0] = Hll + i * dh;
1178                                 xyz[i][j].p[1] = Vll + j * dv;
1179                         }
1180                 }
1181         }
1182
1183         if ( WaveType == WAVE_BITMAP ) {
1184                 GenerateBitmapMapping();
1185         }
1186         /*
1187            else if(WaveType == WAVE_FORMULA)
1188            DoFormula();
1189          */
1190         else
1191         {
1192                 // Initialize Z values using bilinear interpolation
1193                 for ( i = 0; i <= NH; i++ )
1194                 {
1195                         zl = Z00 + i * ( Z10 - Z00 ) / NH;
1196                         zu = Z01 + i * ( Z11 - Z01 ) / NH;
1197                         switch ( Plane )
1198                         {
1199                         case PLANE_XZ0:
1200                         case PLANE_XZ1:
1201                                 for ( j = 0; j <= NV; j++ )
1202                                         xyz[i][j].p[1] = zl + j * ( zu - zl ) / NV;
1203                                 break;
1204                         case PLANE_YZ0:
1205                         case PLANE_YZ1:
1206                                 for ( j = 0; j <= NV; j++ )
1207                                         xyz[i][j].p[0] = zl + j * ( zu - zl ) / NV;
1208                                 break;
1209                         default:
1210                                 for ( j = 0; j <= NV; j++ )
1211                                         xyz[i][j].p[2] = zl + j * ( zu - zl ) / NV;
1212                         }
1213                 }
1214         }
1215
1216         switch ( WaveType )
1217         {
1218         case WAVE_COS_SIN:
1219                 if ( FixBorders ) {
1220                         NHalfcycles = (int)( ( Hur - Hll ) / ( WaveLength / 2. ) );
1221                         NHalfcycles = max( NHalfcycles,1 );
1222                         wh = 2. * ( Hur - Hll ) / NHalfcycles;
1223                         NHalfcycles = (int)( ( Vur - Vll ) / ( WaveLength / 2. ) );
1224                         wv = 2. * ( Vur - Vll ) / NHalfcycles;
1225                         NHalfcycles = max( NHalfcycles,1 );
1226                         i0 = 1;
1227                         i1 = NH - 1;
1228                         j0 = 1;
1229                         j1 = NV - 1;
1230                 }
1231                 else
1232                 {
1233                         wh = WaveLength;
1234                         wv = WaveLength;
1235                         i0 = 0;
1236                         i1 = NH;
1237                         j0 = 0;
1238                         j1 = NV;
1239                 }
1240
1241                 for ( i = i0; i <= i1; i++ )
1242                 {
1243                         h  = Hll + i * dh;
1244                         ha = ( ( h - Hll ) / wh ) * 2. * PI - PI / 2.;
1245                         for ( j = j0; j <= j1; j++ )
1246                         {
1247                                 v  = Vll + j * dv;
1248                                 va = ( ( v - Vll ) / wv ) * 2. * PI;
1249                                 a = Amplitude * cos( ha ) * sin( va );
1250                                 switch ( Plane )
1251                                 {
1252                                 case PLANE_XY1:
1253                                         xyz[i][j].p[2] -= a;
1254                                         break;
1255                                 case PLANE_XZ0:
1256                                         xyz[i][j].p[1] += a;
1257                                         break;
1258                                 case PLANE_XZ1:
1259                                         xyz[i][j].p[1] -= a;
1260                                         break;
1261                                 case PLANE_YZ0:
1262                                         xyz[i][j].p[0] += a;
1263                                         break;
1264                                 case PLANE_YZ1:
1265                                         xyz[i][j].p[0] -= a;
1266                                         break;
1267                                 default:
1268                                         xyz[i][j].p[2] += a;
1269                                 }
1270                         }
1271                 }
1272                 break;
1273         case WAVE_HCYLINDER:
1274                 for ( i = 0; i <= NH; i++ )
1275                 {
1276                         h  = Hll + i * dh;
1277                         ha = ( ( h - Hll ) / WaveLength ) * 2. * PI - PI / 2.;
1278                         for ( j = 0; j <= NV; j++ )
1279                         {
1280                                 a = Amplitude * cos( ha );
1281                                 switch ( Plane )
1282                                 {
1283                                 case PLANE_XY1:
1284                                         xyz[i][j].p[2] -= a;
1285                                         break;
1286                                 case PLANE_XZ0:
1287                                         xyz[i][j].p[1] += a;
1288                                         break;
1289                                 case PLANE_XZ1:
1290                                         xyz[i][j].p[1] -= a;
1291                                         break;
1292                                 case PLANE_YZ0:
1293                                         xyz[i][j].p[0] += a;
1294                                         break;
1295                                 case PLANE_YZ1:
1296                                         xyz[i][j].p[0] -= a;
1297                                         break;
1298                                 default:
1299                                         xyz[i][j].p[2] += a;
1300                                 }
1301                         }
1302                 }
1303                 break;
1304         case WAVE_VCYLINDER:
1305                 for ( i = 0; i <= NH; i++ )
1306                 {
1307                         h  = Hll + i * dh;
1308                         for ( j = 0; j <= NV; j++ )
1309                         {
1310                                 v  = Vll + j * dv;
1311                                 va = ( ( v - Vll ) / WaveLength ) * 2. * PI;
1312                                 a = Amplitude * sin( va );
1313                                 switch ( Plane )
1314                                 {
1315                                 case PLANE_XY1:
1316                                         xyz[i][j].p[2] -= a;
1317                                         break;
1318                                 case PLANE_XZ0:
1319                                         xyz[i][j].p[1] += a;
1320                                         break;
1321                                 case PLANE_XZ1:
1322                                         xyz[i][j].p[1] -= a;
1323                                         break;
1324                                 case PLANE_YZ0:
1325                                         xyz[i][j].p[0] += a;
1326                                         break;
1327                                 case PLANE_YZ1:
1328                                         xyz[i][j].p[0] -= a;
1329                                         break;
1330                                 default:
1331                                         xyz[i][j].p[2] += a;
1332                                 }
1333                         }
1334                 }
1335                 break;
1336         case WAVE_ROUGH_ONLY:
1337                 PlasmaCloud();
1338                 break;
1339         }
1340
1341         if ( WaveType != WAVE_ROUGH_ONLY ) {
1342                 // Fixed values
1343                 for ( i = 0; i <= NH; i++ )
1344                 {
1345                         for ( j = 0; j <= NV; j++ )
1346                         {
1347                                 if ( xyz[i][j].fixed ) {
1348                                         switch ( Plane )
1349                                         {
1350                                         case PLANE_XZ0:
1351                                         case PLANE_XZ1:
1352                                                 xyz[i][j].p[1] = xyz[i][j].fixed_value;
1353                                                 break;
1354                                         case PLANE_YZ0:
1355                                         case PLANE_YZ1:
1356                                                 xyz[i][j].p[0] = xyz[i][j].fixed_value;
1357                                                 break;
1358                                         default:
1359                                                 xyz[i][j].p[2] = xyz[i][j].fixed_value;
1360                                         }
1361
1362                                         if ( xyz[i][j].range > 0 ) {
1363                                                 maxrange = pow( xyz[i][j].range,2 ); // so we don't have to do sqrt's
1364                                                 i0 = i - (int)( floor( xyz[i][j].range / dh - 0.5 ) + 1 );
1365                                                 i1 = i + i - i0;
1366                                                 j0 = j - (int)( floor( xyz[i][j].range / dv - 0.5 ) + 1 );
1367                                                 j1 = j + j - j0;
1368                                                 if ( FixBorders ) {
1369                                                         i0 = max( i0,1 );
1370                                                         i1 = min( i1,NH - 1 );
1371                                                         j0 = max( j0,1 );
1372                                                         j1 = min( j1,NV - 1 );
1373                                                 }
1374                                                 else
1375                                                 {
1376                                                         i0 = max( i0,0 );
1377                                                         i1 = min( i1,NH );
1378                                                         j0 = max( j0,0 );
1379                                                         j1 = min( j1,NV );
1380                                                 }
1381                                                 for ( ii = i0; ii <= i1; ii++ )
1382                                                 {
1383                                                         for ( jj = j0; jj <= j1; jj++ )
1384                                                         {
1385                                                                 if ( ii == i && jj == j ) {
1386                                                                         continue;
1387                                                                 }
1388                                                                 range = pow( dh * ( i - ii ), 2 ) + pow( dv * ( j - jj ), 2 );
1389                                                                 if ( range > maxrange ) {
1390                                                                         continue;
1391                                                                 }
1392                                                                 dr = sqrt( range / maxrange );
1393                                                                 rate = max( -30.,min( xyz[i][j].rate,30. ) );
1394                                                                 if ( rate < -1. ) {
1395                                                                         delta = pow( ( 1. - dr ),-rate + 1. );
1396                                                                 }
1397                                                                 else if ( rate < 0. ) {
1398                                                                         delta = ( 1 + rate ) * 0.5 * ( cos( dr * PI ) + 1.0 ) -
1399                                                                                         rate*pow( ( 1. - dr ),2 );
1400                                                                 }
1401                                                                 else if ( rate == 0. ) {
1402                                                                         delta = 0.5 * ( cos( dr * PI ) + 1.0 );
1403                                                                 }
1404                                                                 else if ( rate <= 1. ) {
1405                                                                         delta = ( 1. - rate ) * 0.5 * ( cos( dr * PI ) + 1.0 ) +
1406                                                                                         rate * ( 1. - pow( dr,2 ) );
1407                                                                 }
1408                                                                 else
1409                                                                 {
1410                                                                         delta = 1. - pow( dr,rate + 1 );
1411                                                                 }
1412                                                                 switch ( Plane )
1413                                                                 {
1414                                                                 case PLANE_XZ0:
1415                                                                 case PLANE_XZ1:
1416                                                                         xyz[ii][jj].p[1] += ( xyz[i][j].p[1] - xyz[ii][jj].p[1] ) * delta;
1417                                                                         break;
1418                                                                 case PLANE_YZ0:
1419                                                                 case PLANE_YZ1:
1420                                                                         xyz[ii][jj].p[0] += ( xyz[i][j].p[0] - xyz[ii][jj].p[0] ) * delta;
1421                                                                         break;
1422                                                                 default:
1423                                                                         xyz[ii][jj].p[2] += ( xyz[i][j].p[2] - xyz[ii][jj].p[2] ) * delta;
1424                                                                 }
1425                                                         }
1426                                                 }
1427                                         }
1428                                 }
1429                         }
1430                 }
1431         }
1432
1433         if ( ( Roughness > 0. ) && ( WaveType != WAVE_ROUGH_ONLY ) ) {
1434                 for ( i = 0; i <= NH; i++ )
1435                 {
1436                         for ( j = 0; j <= NV; j++ )
1437                         {
1438                                 if ( CanEdit( i,j ) && !xyz[i][j].fixed ) {
1439                                         switch ( Plane )
1440                                         {
1441                                         case PLANE_XZ0:
1442                                         case PLANE_XZ1:
1443                                                 xyz[i][j].p[1] += -Roughness / 2. + Roughness * ( (double)rand() / (double)RAND_MAX );
1444                                                 break;
1445                                         case PLANE_YZ0:
1446                                         case PLANE_YZ1:
1447                                                 xyz[i][j].p[0] += -Roughness / 2. + Roughness * ( (double)rand() / (double)RAND_MAX );
1448                                                 break;
1449                                         default:
1450                                                 xyz[i][j].p[2] += -Roughness / 2. + Roughness * ( (double)rand() / (double)RAND_MAX );
1451                                         }
1452                                 }
1453                                 else{
1454                                         r = rand(); // We still get a random number, so that fixing points
1455                                 }
1456                                 // doesn't change the sequence.
1457
1458                         }
1459                 }
1460         }
1461
1462         for ( i = 0; i <= NH; i++ )
1463         {
1464                 for ( j = 0; j <= NV; j++ )
1465                 {
1466                         for ( k = 0; k < 3; k++ )
1467                         {
1468                                 xyz[i][j].p[k] = Nearest( xyz[i][j].p[k],2.0 );
1469                         }
1470                 }
1471         }
1472
1473         // Find minima and maxima
1474         switch ( Plane )
1475         {
1476         case PLANE_XZ0:
1477         case PLANE_XZ1:
1478                 xmin = Hll;
1479                 xmax = Hur;
1480                 zmin = Vll;
1481                 zmax = Vur;
1482                 ymin = xyz[0][0].p[1];
1483                 ymax = ymin;
1484                 for ( i = 0; i <= NH; i++ )
1485                 {
1486                         for ( j = 0; j <= NV; j++ )
1487                         {
1488                                 ymin = min( ymin,xyz[i][j].p[1] );
1489                                 ymax = max( ymax,xyz[i][j].p[1] );
1490                         }
1491                 }
1492                 break;
1493         case PLANE_YZ0:
1494         case PLANE_YZ1:
1495                 ymin = Hll;
1496                 ymax = Hur;
1497                 zmin = Vll;
1498                 zmax = Vur;
1499                 xmin = xyz[0][0].p[0];
1500                 xmax = ymin;
1501                 for ( i = 0; i <= NH; i++ )
1502                 {
1503                         for ( j = 0; j <= NV; j++ )
1504                         {
1505                                 xmin = min( xmin,xyz[i][j].p[0] );
1506                                 xmax = max( xmax,xyz[i][j].p[0] );
1507                         }
1508                 }
1509                 break;
1510                 break;
1511         default:
1512                 xmin = Hll;
1513                 xmax = Hur;
1514                 ymin = Vll;
1515                 ymax = Vur;
1516                 zmin = xyz[0][0].p[2];
1517                 zmax = zmin;
1518                 for ( i = 0; i <= NH; i++ )
1519                 {
1520                         for ( j = 0; j <= NV; j++ )
1521                         {
1522                                 zmin = min( zmin,xyz[i][j].p[2] );
1523                                 zmax = max( zmax,xyz[i][j].p[2] );
1524                         }
1525                 }
1526         }
1527
1528         xmin = Nearest( xmin,2. );
1529         xmax = Nearest( xmax,2. );
1530         ymin = Nearest( ymin,2. );
1531         ymax = Nearest( ymax,2. );
1532         zmin = Nearest( zmin,2. );
1533         zmax = Nearest( zmax,2. );
1534
1535         switch ( Plane )
1536         {
1537         case PLANE_XY1:
1538                 backface = AtLeast( zmax + 32.,32. );
1539                 break;
1540         case PLANE_XZ0:
1541                 backface = NoMoreThan( ymin - 32.,32. );
1542                 break;
1543         case PLANE_XZ1:
1544                 backface = AtLeast( ymax + 32.,32. );
1545                 break;
1546         case PLANE_YZ0:
1547                 backface = NoMoreThan( xmin - 32.,32. );
1548                 break;
1549         case PLANE_YZ1:
1550                 backface = AtLeast( xmax + 32.,32. );
1551                 break;
1552         default:
1553                 backface = NoMoreThan( zmin - 32.,32. );
1554         }
1555
1556         if ( gNode ) {
1557                 free( gNode );
1558                 free( gTri );
1559                 gNode = (NODE *)NULL;
1560                 gTri  = (TRI *)NULL;
1561         }
1562         if ( Decimate > 0 && ( Game != QUAKE3 || UsePatches == 0 ) ) {
1563                 MakeDecimatedMap( &gNumNodes,&gNumTris,&gNode,&gTri );
1564         }
1565         else
1566         {
1567                 gNumNodes = ( NH + 1 ) * ( NV + 1 );
1568                 gNumTris  = NH * NV * 2;
1569                 gNode = (NODE *) malloc( gNumNodes * sizeof( NODE ) );
1570                 gTri = (TRI *) malloc( gNumTris * sizeof( TRI ) );
1571
1572                 for ( i = 0,N = 0; i <= NH; i++ )
1573                 {
1574                         for ( j = 0; j <= NV; j++, N++ )
1575                         {
1576                                 gNode[N].used = 1;
1577                                 gNode[N].p[0] = (float)xyz[i][j].p[0];
1578                                 gNode[N].p[1] = (float)xyz[i][j].p[1];
1579                                 gNode[N].p[2] = (float)xyz[i][j].p[2];
1580                         }
1581                 }
1582
1583                 for ( i = 0; i < NH; i++ )
1584                 {
1585                         for ( j = 0; j < NV; j++ )
1586                         {
1587                                 k = i * NV * 2 + j * 2;
1588                                 if ( ( i + j ) % 2 ) {
1589                                         switch ( Plane )
1590                                         {
1591                                         case PLANE_XY1:
1592                                         case PLANE_XZ1:
1593                                         case PLANE_YZ1:
1594                                                 gTri[k  ].v[0] = i * ( NV + 1 ) + j;
1595                                                 gTri[k  ].v[1] = ( i + 1 ) * ( NV + 1 ) + j + 1;
1596                                                 gTri[k  ].v[2] = ( i + 1 ) * ( NV + 1 ) + j;
1597                                                 gTri[k + 1].v[0] = i * ( NV + 1 ) + j;
1598                                                 gTri[k + 1].v[1] = i * ( NV + 1 ) + j + 1;
1599                                                 gTri[k + 1].v[2] = ( i + 1 ) * ( NV + 1 ) + j + 1;
1600                                                 break;
1601                                         default:
1602                                                 gTri[k  ].v[0] = i * ( NV + 1 ) + j;
1603                                                 gTri[k  ].v[1] = ( i + 1 ) * ( NV + 1 ) + j;
1604                                                 gTri[k  ].v[2] = ( i + 1 ) * ( NV + 1 ) + j + 1;
1605                                                 gTri[k + 1].v[0] = i * ( NV + 1 ) + j;
1606                                                 gTri[k + 1].v[1] = ( i + 1 ) * ( NV + 1 ) + j + 1;
1607                                                 gTri[k + 1].v[2] = i * ( NV + 1 ) + j + 1;
1608                                         }
1609                                 }
1610                                 else
1611                                 {
1612                                         switch ( Plane )
1613                                         {
1614                                         case PLANE_XY1:
1615                                         case PLANE_XZ1:
1616                                         case PLANE_YZ1:
1617                                                 gTri[k  ].v[0] = i * ( NV + 1 ) + j;
1618                                                 gTri[k  ].v[1] = i * ( NV + 1 ) + j + 1;
1619                                                 gTri[k  ].v[2] = ( i + 1 ) * ( NV + 1 ) + j;
1620                                                 gTri[k + 1].v[0] = ( i + 1 ) * ( NV + 1 ) + j;
1621                                                 gTri[k + 1].v[1] = i * ( NV + 1 ) + j + 1;
1622                                                 gTri[k + 1].v[2] = ( i + 1 ) * ( NV + 1 ) + j + 1;
1623                                                 break;
1624                                         default:
1625                                                 gTri[k  ].v[0] = i * ( NV + 1 ) + j;
1626                                                 gTri[k  ].v[1] = ( i + 1 ) * ( NV + 1 ) + j;
1627                                                 gTri[k  ].v[2] = i * ( NV + 1 ) + j + 1;
1628                                                 gTri[k + 1].v[0] = ( i + 1 ) * ( NV + 1 ) + j;
1629                                                 gTri[k + 1].v[1] = ( i + 1 ) * ( NV + 1 ) + j + 1;
1630                                                 gTri[k + 1].v[2] = i * ( NV + 1 ) + j + 1;
1631                                         }
1632                                 }
1633                         }
1634                 }
1635         }
1636 /*
1637    sprintf(CSV,"csv%03d.csv",Decimate);
1638    f = fopen(CSV,"w");
1639    for(i=0; i<gNumNodes; i++)
1640    {
1641     if(gNode[i].used)
1642       fprintf(f,"%g,%g,%g\n",gNode[i].p[0],gNode[i].p[1],gNode[i].p[2]);
1643    }
1644    fclose(f);
1645  */
1646         for ( i = 0; i < gNumTris; i++ )
1647                 PlaneFromPoints( gNode[gTri[i].v[0]].p,
1648                                                  gNode[gTri[i].v[1]].p,
1649                                                  gNode[gTri[i].v[2]].p,
1650                                                  &gTri[i].plane );
1651
1652         // Hydra: snap-to-grid begin
1653         if ( SnapToGrid > 0 ) {
1654                 for ( i = 0; i < NH; i++ )
1655                 {
1656                         for ( j = 0; j < NV; j++ )
1657                         {
1658                                 switch ( Plane )
1659                                 {
1660                                 case PLANE_XZ0:
1661                                 case PLANE_XZ1:
1662                                         xyz[i][j].p[1] = CalculateSnapValue( xyz[i][j].p[1] );
1663                                         break;
1664                                 case PLANE_YZ0:
1665                                 case PLANE_YZ1:
1666                                         xyz[i][j].p[0] = CalculateSnapValue( xyz[i][j].p[0] );
1667                                         break;
1668                                 default:
1669                                         xyz[i][j].p[2] = CalculateSnapValue( xyz[i][j].p[2] );
1670                                 }
1671                         }
1672                 }
1673         }
1674         // Hydra: snap-to-grid end
1675 }
1676 //=============================================================
1677 double Nearest( double x, double dx ){
1678         double xx;
1679
1680         xx = (double)( floor( x / dx - 0.5 ) + 1. ) * dx;
1681         if ( fabs( xx ) < dx / 2 ) {
1682                 xx = 0.;
1683         }
1684         return xx;
1685 }
1686 //=============================================================
1687 double NoMoreThan( double x, double dx ){
1688         double xx;
1689
1690         xx = (double)( floor( x / dx - 0.5 ) + 1. ) * dx;
1691         if ( xx > x ) {
1692                 xx -= dx;
1693         }
1694         return xx;
1695 }
1696 //=============================================================
1697 double AtLeast( double x, double dx ){
1698         double xx;
1699
1700         xx = (double)( floor( x / dx - 0.5 ) + 1. ) * dx;
1701         if ( xx < x ) {
1702                 xx += dx;
1703         }
1704         return xx;
1705 }
1706 //=============================================================
1707 double LessThan( double x,double dx ){
1708         double xx;
1709
1710         xx = (double)( floor( x / dx - 0.5 ) + 1. ) * dx;
1711         if ( xx >= x ) {
1712                 xx -= dx;
1713         }
1714         return xx;
1715 }
1716 //=============================================================
1717 double MoreThan( double x,double dx ){
1718         double xx;
1719
1720         xx = (double)( floor( x / dx - 0.5 ) + 1. ) * dx;
1721         while ( xx <= x )
1722                 xx += dx;
1723         return xx;
1724 }
1725 //=============================================================
1726 void SubdividePlasma( int i0,int j0,int i1,int j1 ){
1727         int i, j;
1728         double z1, z2;
1729         double r;    // NOTE: This is used to keep the random number sequence the same
1730                      //       when we fix a point. If we did NOT do this, then simply
1731                      //       fixing a point at its current value would change the entire
1732                      //       surface.
1733
1734         i = ( i0 + i1 ) / 2;
1735         j = ( j0 + j1 ) / 2;
1736         if ( i1 > i0 + 1 ) {
1737                 if ( !xyz[i][j0].done ) {
1738                         xyz[i][j0].pp[2] = xyz[i0][j0].pp[2] +
1739                                                            ( xyz[i1][j0].pp[2] - xyz[i0][j0].pp[2] ) * (double)( i - i0 ) / (double)( i1 - i0 ) +
1740                                                            ( (double)( i - i0 ) ) * ( -Roughness / 2. + Roughness * ( (double)rand() / (double)RAND_MAX ) );
1741                         xyz[i][j0].done = 1;
1742                 }
1743                 else{
1744                         r = rand();
1745                 }
1746                 if ( ( j1 > j0 ) && ( !xyz[i][j1].done ) ) {
1747                         xyz[i][j1].pp[2] = xyz[i0][j1].pp[2] +
1748                                                            ( xyz[i1][j1].pp[2] - xyz[i0][j1].pp[2] ) * (double)( i - i0 ) / (double)( i1 - i0 ) +
1749                                                            ( (double)( i - i0 ) ) * ( -Roughness / 2. + Roughness * ( (double)rand() / (double)RAND_MAX ) );
1750                         xyz[i][j1].done = 1;
1751                 }
1752                 else{
1753                         r = rand();
1754                 }
1755         }
1756         if ( j1 > j0 + 1 ) {
1757                 if ( !xyz[i0][j].done ) {
1758                         xyz[i0][j].pp[2] = xyz[i0][j0].pp[2] +
1759                                                            ( xyz[i0][j1].pp[2] - xyz[i0][j0].pp[2] ) * (double)( j - j0 ) / (double)( j1 - j0 ) +
1760                                                            ( (double)( j - j0 ) ) * ( -Roughness / 2. + Roughness * ( (double)rand() / (double)RAND_MAX ) );
1761                         xyz[i0][j].done = 1;
1762                 }
1763                 else{
1764                         r = rand();
1765                 }
1766                 if ( ( i1 > i0 ) && ( !xyz[i1][j].done ) ) {
1767                         xyz[i1][j].pp[2] = xyz[i1][j0].pp[2] +
1768                                                            ( xyz[i1][j1].pp[2] - xyz[i1][j0].pp[2] ) * (double)( j - j0 ) / (double)( j1 - j0 ) +
1769                                                            ( (double)( j - j0 ) ) * ( -Roughness / 2. + Roughness * ( (double)rand() / (double)RAND_MAX ) );
1770                         xyz[i1][j].done = 1;
1771                 }
1772                 else{
1773                         r = rand();
1774                 }
1775         }
1776         if ( ( i1 > i0 + 1 ) && ( j1 > j0 + 1 ) ) {
1777                 if ( !xyz[i][j].done ) {
1778                         z1 = xyz[i0][j].pp[2] +
1779                                  ( xyz[i1][j].pp[2] - xyz[i0][j].pp[2] ) * (double)( i - i0 ) / (double)( i1 - i0 );
1780                         z2 = xyz[i][j0].pp[2] +
1781                                  ( xyz[i][j1].pp[2] - xyz[i][j0].pp[2] ) * (double)( j - j0 ) / (double)( j1 - j0 );
1782                         xyz[i][j].pp[2] = ( z1 + z2 ) / 2. +
1783                                                           ( (double)( i - i0 ) ) * ( -Roughness / 2. + Roughness * ( (double)rand() / (double)RAND_MAX ) );
1784                         xyz[i][j].done = 1;
1785                 }
1786                 else{
1787                         r = rand();
1788                 }
1789         }
1790         if ( i > i0 + 1 || j > j0 + 1 ) {
1791                 SubdividePlasma( i0,j0,i,j );
1792         }
1793         if ( i1 > i + 1 || j > j0 + 1 ) {
1794                 SubdividePlasma( i,j0,i1,j );
1795         }
1796         if ( i > i0 + 1 || j1 > j0 + 1 ) {
1797                 SubdividePlasma( i0,j,i,j1 );
1798         }
1799         if ( i1 > i + 1 || j1 > j0 + 1 ) {
1800                 SubdividePlasma( i,j,i1,j1 );
1801         }
1802 }
1803 //==================================================================================
1804 void PlasmaCloud(){
1805         int i, j;
1806         /* use pp[2] values until done to avoid messing with a bunch of
1807            switch statements */
1808
1809         for ( i = 0; i <= NH; i++ )
1810         {
1811                 for ( j = 0; j <= NV; j++ )
1812                 {
1813                         if ( FixedPoint( i,j ) ) {
1814                                 xyz[i][j].done = 1;
1815                         }
1816                         else{
1817                                 xyz[i][j].done = 0;
1818                         }
1819                 }
1820         }
1821
1822         switch ( Plane )
1823         {
1824         case PLANE_XZ0:
1825         case PLANE_XZ1:
1826                 for ( i = 0; i <= NH; i++ )
1827                 {
1828                         for ( j = 0; j <= NV; j++ )
1829                         {
1830                                 if ( xyz[i][j].fixed ) {
1831                                         xyz[i][j].pp[2] = xyz[i][j].fixed_value;
1832                                 }
1833                                 else{
1834                                         xyz[i][j].pp[2] = xyz[i][j].p[1];
1835                                 }
1836                         }
1837                 }
1838                 break;
1839         case PLANE_YZ0:
1840         case PLANE_YZ1:
1841                 for ( i = 0; i <= NH; i++ )
1842                 {
1843                         for ( j = 0; j <= NV; j++ )
1844                         {
1845                                 if ( xyz[i][j].fixed ) {
1846                                         xyz[i][j].pp[2] = xyz[i][j].fixed_value;
1847                                 }
1848                                 else{
1849                                         xyz[i][j].pp[2] = xyz[i][j].p[0];
1850                                 }
1851                         }
1852                 }
1853                 break;
1854         default:
1855                 for ( i = 0; i <= NH; i++ )
1856                 {
1857                         for ( j = 0; j <= NV; j++ )
1858                         {
1859                                 if ( xyz[i][j].fixed ) {
1860                                         xyz[i][j].pp[2] = xyz[i][j].fixed_value;
1861                                 }
1862                                 else{
1863                                         xyz[i][j].pp[2] = xyz[i][j].p[2];
1864                                 }
1865                         }
1866                 }
1867                 break;
1868         }
1869         SubdividePlasma( 0,0,NH,NV );
1870         switch ( Plane )
1871         {
1872         case PLANE_XZ0:
1873         case PLANE_XZ1:
1874                 for ( i = 0; i <= NH; i++ )
1875                 {
1876                         for ( j = 0; j <= NV; j++ )
1877                         {
1878                                 xyz[i][j].p[1] = xyz[i][j].pp[2];
1879                         }
1880                 }
1881                 break;
1882         case PLANE_YZ0:
1883         case PLANE_YZ1:
1884                 for ( i = 0; i <= NH; i++ )
1885                 {
1886                         for ( j = 0; j <= NV; j++ )
1887                         {
1888                                 xyz[i][j].p[0] = xyz[i][j].pp[2];
1889                         }
1890                 }
1891                 break;
1892         default:
1893                 for ( i = 0; i <= NH; i++ )
1894                 {
1895                         for ( j = 0; j <= NV; j++ )
1896                         {
1897                                 xyz[i][j].p[2] = xyz[i][j].pp[2];
1898                         }
1899                 }
1900                 break;
1901         }
1902 }
1903 //===========================================================================
1904 bool FixedPoint( int i, int j ){
1905         if ( xyz[i][j].fixed ) {
1906                 return TRUE;
1907         }
1908         return !CanEdit( i,j );
1909 }
1910 //===========================================================================
1911 bool CanEdit( int i, int j ){
1912         if ( FixBorders && ( ( WaveType == WAVE_COS_SIN ) || ( WaveType == WAVE_ROUGH_ONLY ) ) ) {
1913                 if ( i == 0 ) {
1914                         return FALSE;
1915                 }
1916                 if ( i == NH ) {
1917                         return FALSE;
1918                 }
1919                 if ( j == 0 ) {
1920                         return FALSE;
1921                 }
1922                 if ( j == NV ) {
1923                         return FALSE;
1924                 }
1925         }
1926         if ( i == 0 && j == 0 ) {
1927                 return FALSE;
1928         }
1929         if ( i == NH && j == 0 ) {
1930                 return FALSE;
1931         }
1932         if ( i == 0 && j == NV ) {
1933                 return FALSE;
1934         }
1935         if ( i == NH && j == NV ) {
1936                 return FALSE;
1937         }
1938         return TRUE;
1939 }
1940 /*============================================================================
1941    TriangleFromPoint
1942    Determines which triangle in the gTri array bounds the input point. Doesn't
1943    do anything special with border points.
1944  */
1945 int TriangleFromPoint( double x, double y ){
1946         int j, tri;
1947
1948         if ( !gTri ) {
1949                 return -1;
1950         }
1951
1952         for ( j = 0, tri = -1; j < gNumTris && tri == -1; j++ )
1953         {
1954                 if ( side( x,y,
1955                                    gNode[gTri[j].v[0]].p[0],gNode[gTri[j].v[0]].p[1],
1956                                    gNode[gTri[j].v[1]].p[0],gNode[gTri[j].v[1]].p[1] ) < 0. ) {
1957                         continue;
1958                 }
1959                 if ( side( x,y,
1960                                    gNode[gTri[j].v[1]].p[0],gNode[gTri[j].v[1]].p[1],
1961                                    gNode[gTri[j].v[2]].p[0],gNode[gTri[j].v[2]].p[1] ) < 0. ) {
1962                         continue;
1963                 }
1964                 if ( side( x,y,
1965                                    gNode[gTri[j].v[2]].p[0],gNode[gTri[j].v[2]].p[1],
1966                                    gNode[gTri[j].v[0]].p[0],gNode[gTri[j].v[0]].p[1] ) < 0. ) {
1967                         continue;
1968                 }
1969                 tri = j;
1970         }
1971
1972         return tri;
1973 }
1974 /*============================================================================
1975    PlayerStartZ
1976    Determines minimum height to place the player start such that he doesn't
1977    intersect any surface brushes.
1978  */
1979 int PlayerStartZ( double x, double y ){
1980         int k,t[5];
1981         double z, zt;
1982
1983         if ( !gTri ) {
1984                 return (int)zmax;
1985         }
1986
1987         t[0] = TriangleFromPoint( x,y );
1988         t[1] = TriangleFromPoint( x + PlayerBox[Game].x[0],y + PlayerBox[Game].y[0] );
1989         t[2] = TriangleFromPoint( x + PlayerBox[Game].x[0],y + PlayerBox[Game].y[1] );
1990         t[3] = TriangleFromPoint( x + PlayerBox[Game].x[1],y + PlayerBox[Game].y[0] );
1991         t[4] = TriangleFromPoint( x + PlayerBox[Game].x[1],y + PlayerBox[Game].y[1] );
1992         z = zmin;
1993         for ( k = 0; k < 5; k++ )
1994         {
1995                 zt = ( gTri[t[k]].plane.dist -
1996                            gTri[t[k]].plane.normal[0] * x -
1997                            gTri[t[k]].plane.normal[1] * y   ) /
1998                          gTri[t[k]].plane.normal[2];
1999                 z = max( z,zt );
2000         }
2001         return (int)( AtLeast( z,2. ) - PlayerBox[Game].z[0] );
2002 }
2003 //=============================================================
2004 void XYZtoV( XYZ *xyz, vec3 *v ){
2005         v[0][0] = (vec)Nearest( xyz->p[0],2. );
2006         v[0][1] = (vec)Nearest( xyz->p[1],2. );
2007         v[0][2] = (vec)Nearest( xyz->p[2],2. );
2008 }
2009
2010 //=============================================================
2011 void MakePatch( patchMesh_t *p ){
2012         int ret;
2013         char shadername[64 + 9];
2014
2015         ret = g_FuncTable.m_pfnCreatePatchHandle();
2016         // strcpy(shadername, "textures/");
2017         // strcpy(shadername+9, Texture[Game][0]);
2018         strcpy( shadername, Texture[Game][0] );
2019         g_FuncTable.m_pfnCommitPatchHandleToMap( ret,p,shadername );
2020         g_FuncTable.m_pfnReleasePatchHandles();
2021 }
2022
2023 //=============================================================
2024 void MakeBrush( BRUSH *brush ){
2025         LPVOID vp;
2026         int i;
2027         _QERFaceData QERFaceData;
2028
2029         if ( g_FuncTable.m_pfnCreateBrushHandle == NULL ) {
2030                 g_FuncTable.m_pfnMessageBox( g_pRadiantWnd,"m_pfnCreateBrushHandle==NULL","Aw damn",0, NULL );
2031                 return;
2032         }
2033         vp = ( g_FuncTable.m_pfnCreateBrushHandle )();
2034         if ( !vp ) {
2035                 return;
2036         }
2037         for ( i = 0; i < brush->NumFaces; i++ )
2038         {
2039                 if ( !strncmp( brush->face[i].texture, "textures/", 9 ) ) {
2040                         strcpy( QERFaceData.m_TextureName,brush->face[i].texture );
2041                 }
2042                 else
2043                 {
2044                         strcpy( QERFaceData.m_TextureName,"textures/" );
2045                         strcpy( QERFaceData.m_TextureName + 9,brush->face[i].texture );
2046                 }
2047                 QERFaceData.m_nContents = brush->face[i].Contents;
2048                 QERFaceData.m_nFlags    = brush->face[i].Surface;
2049                 QERFaceData.m_nValue    = brush->face[i].Value;
2050                 QERFaceData.m_fShift[0] = brush->face[i].Shift[0];
2051                 QERFaceData.m_fShift[1] = brush->face[i].Shift[1];
2052                 QERFaceData.m_fRotate   = brush->face[i].Rotate;
2053                 QERFaceData.m_fScale[0] = brush->face[i].Scale[0];
2054                 QERFaceData.m_fScale[1] = brush->face[i].Scale[1];
2055                 QERFaceData.m_v1[0]     = brush->face[i].v[0][0];
2056                 QERFaceData.m_v1[1]     = brush->face[i].v[0][1];
2057                 QERFaceData.m_v1[2]     = brush->face[i].v[0][2];
2058                 QERFaceData.m_v2[0]     = brush->face[i].v[1][0];
2059                 QERFaceData.m_v2[1]     = brush->face[i].v[1][1];
2060                 QERFaceData.m_v2[2]     = brush->face[i].v[1][2];
2061                 QERFaceData.m_v3[0]     = brush->face[i].v[2][0];
2062                 QERFaceData.m_v3[1]     = brush->face[i].v[2][1];
2063                 QERFaceData.m_v3[2]     = brush->face[i].v[2][2];
2064                 QERFaceData.m_bBPrimit  = false;
2065                 ( g_FuncTable.m_pfnAddFaceData )( vp,&QERFaceData );
2066         }
2067         if ( g_FuncTable.m_pfnCommitBrushHandle != NULL ) {
2068                 if ( h_func_group ) {
2069                         g_FuncTable.m_pfnCommitBrushHandleToEntity( vp,h_func_group );
2070                 }
2071                 else{
2072                         g_FuncTable.m_pfnCommitBrushHandle( vp );
2073                 }
2074         }
2075 }
2076 //=============================================================
2077 void OpenFuncGroup(){
2078         if ( g_FuncTable.m_pfnAllocateEpair != NULL ) {
2079                 epair_t *ep;
2080
2081                 h_func_group = g_FuncTable.m_pfnCreateEntityHandle();
2082                 ep = g_EntityTable.m_pfnAllocateEpair( "classname","func_group" );
2083                 g_EntityTable.m_pfnSetEntityKeyValList( (entity_t *)h_func_group,ep );
2084
2085                 if ( AddTerrainKey ) { // ^Fishman - Add terrain key to func_group.
2086                         epair_t *ep2;
2087                         terrainkey = g_FuncTable.m_pfnCreateEntityHandle();
2088                         ep2 = g_EntityTable.m_pfnAllocateEpair( "terrain","1" );
2089                         ep->next = ep2;
2090                         g_EntityTable.m_pfnSetEntityKeyValList( (entity_t *)h_func_group,ep );
2091                 }
2092         }
2093         else{
2094                 h_func_group = NULL;
2095         }
2096 }
2097 //=============================================================
2098 void CloseFuncGroup(){
2099         if ( h_func_group ) {
2100                 g_FuncTable.m_pfnCommitEntityHandleToMap( h_func_group );
2101         }
2102         if ( g_FuncTable.m_pfnSysUpdateWindows != NULL ) {
2103                 g_FuncTable.m_pfnSysUpdateWindows( W_ALL );
2104         }
2105 }