]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - tools/quake3/q3map2/prtfile.c
enable q3map2 out of tree compilation
[xonotic/netradiant.git] / tools / quake3 / q3map2 / prtfile.c
index 6f36f7582cb554000541e5b6b4579199df6d86d9..2cd7015c35acb47090c90e996b8121cfcfdb9a25 100644 (file)
@@ -1,30 +1,30 @@
 /* -------------------------------------------------------------------------------
 
-Copyright (C) 1999-2007 id Software, Inc. and contributors.
-For a list of contributors, see the accompanying CONTRIBUTORS file.
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
 
-This file is part of GtkRadiant.
+   This file is part of GtkRadiant.
 
-GtkRadiant is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+   GtkRadiant is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
 
-GtkRadiant is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
+   GtkRadiant is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
 
-You should have received a copy of the GNU General Public License
-along with GtkRadiant; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+   You should have received a copy of the GNU General Public License
+   along with GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
-----------------------------------------------------------------------------------
+   ----------------------------------------------------------------------------------
 
-This code has been altered significantly from its original form, to support
-several games based on the Quake III Arena engine, in the form of "Q3Map2."
+   This code has been altered significantly from its original form, to support
+   several games based on the Quake III Arena engine, in the form of "Q3Map2."
 
-------------------------------------------------------------------------------- */
+   ------------------------------------------------------------------------------- */
 
 
 
@@ -39,176 +39,272 @@ several games based on the Quake III Arena engine, in the form of "Q3Map2."
 
 
 /*
-==============================================================================
+   ==============================================================================
 
-PORTAL FILE GENERATION
+   PORTAL FILE GENERATION
 
-Save out name.prt for qvis to read
-==============================================================================
-*/
+   Save out name.prt for qvis to read
+   ==============================================================================
+ */
 
 
-#define        PORTALFILE      "PRT1"
+#define PORTALFILE  "PRT1"
 
-FILE   *pf;
-int            num_visclusters;                                // clusters the player can be in
-int            num_visportals;
-int            num_solidfaces;
+FILE    *pf;
+int num_visclusters;                    // clusters the player can be in
+int num_visportals;
+int num_solidfaces;
 
-void WriteFloat (FILE *f, vec_t v)
-{
-       if ( fabs(v - Q_rint(v)) < 0.001 )
-               fprintf (f,"%i ",(int)Q_rint(v));
-       else
-               fprintf (f,"%f ",v);
+void WriteFloat( FILE *f, vec_t v ){
+       if ( fabs( v - Q_rint( v ) ) < 0.001 ) {
+               fprintf( f,"%i ",(int)Q_rint( v ) );
+       }
+       else{
+               fprintf( f,"%f ",v );
+       }
+}
+
+void CountVisportals_r( node_t *node ){
+       int s;
+       portal_t    *p;
+       winding_t   *w;
+
+       // decision node
+       if ( node->planenum != PLANENUM_LEAF ) {
+               CountVisportals_r( node->children[0] );
+               CountVisportals_r( node->children[1] );
+               return;
+       }
+
+       if ( node->opaque ) {
+               return;
+       }
+
+       for ( p = node->portals ; p ; p = p->next[s] )
+       {
+               w = p->winding;
+               s = ( p->nodes[1] == node );
+               if ( w && p->nodes[0] == node ) {
+                       if ( !PortalPassable( p ) ) {
+                               continue;
+                       }
+                       if ( p->nodes[0]->cluster == p->nodes[1]->cluster ) {
+                               continue;
+                       }
+                       ++num_visportals;
+               }
+       }
 }
 
 /*
-=================
-WritePortalFile_r
-=================
-*/
-void WritePortalFile_r (node_t *node)
-{
-       int                     i, s;   
-       portal_t        *p;
-       winding_t       *w;
-       vec3_t          normal;
-       vec_t           dist;
+   =================
+   WritePortalFile_r
+   =================
+ */
+void WritePortalFile_r( node_t *node ){
+       int i, s, flags;
+       portal_t    *p;
+       winding_t   *w;
+       vec3_t normal;
+       vec_t dist;
 
        // decision node
-       if (node->planenum != PLANENUM_LEAF) {
-               WritePortalFile_r (node->children[0]);
-               WritePortalFile_r (node->children[1]);
+       if ( node->planenum != PLANENUM_LEAF ) {
+               WritePortalFile_r( node->children[0] );
+               WritePortalFile_r( node->children[1] );
                return;
        }
-       
-       if (node->opaque) {
+
+       if ( node->opaque ) {
                return;
        }
 
-       for (p = node->portals ; p ; p=p->next[s])
+       for ( p = node->portals ; p ; p = p->next[s] )
        {
                w = p->winding;
-               s = (p->nodes[1] == node);
-               if (w && p->nodes[0] == node)
-               {
-                       if (!PortalPassable(p))
+               s = ( p->nodes[1] == node );
+               if ( w && p->nodes[0] == node ) {
+                       if ( !PortalPassable( p ) ) {
+                               continue;
+                       }
+                       if ( p->nodes[0]->cluster == p->nodes[1]->cluster ) {
                                continue;
+                       }
+                       --num_visportals;
                        // write out to the file
-                       
+
                        // sometimes planes get turned around when they are very near
                        // the changeover point between different axis.  interpret the
                        // plane the same way vis will, and flip the side orders if needed
                        // FIXME: is this still relevent?
-                       WindingPlane (w, normal, &dist);
-                       if ( DotProduct (p->plane.normal, normal) < 0.99 )
-                       {       // backwards...
-                               fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[1]->cluster, p->nodes[0]->cluster);
+                       WindingPlane( w, normal, &dist );
+
+                       if ( DotProduct( p->plane.normal, normal ) < 0.99 ) { // backwards...
+                               fprintf( pf,"%i %i %i ",w->numpoints, p->nodes[1]->cluster, p->nodes[0]->cluster );
                        }
-                       else
-                               fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[0]->cluster, p->nodes[1]->cluster);
-                       
+                       else{
+                               fprintf( pf,"%i %i %i ",w->numpoints, p->nodes[0]->cluster, p->nodes[1]->cluster );
+                       }
+
+                       flags = 0;
+
                        /* ydnar: added this change to make antiportals work */
-                       if( p->compileFlags & C_HINT )
-                               fprintf( pf, "1 " );
-                       else
-                               fprintf( pf, "0 " );
-                       
+                       if( p->compileFlags & C_HINT ) {
+                               flags |= 1;
+                       }
+
+                       /* divVerent: I want farplanedist to not kill skybox. So... */
+                       if( p->compileFlags & C_SKY ) {
+                               flags |= 2;
+                       }
+
+                       fprintf( pf, "%d ", flags );
+
                        /* write the winding */
-                       for (i=0 ; i<w->numpoints ; i++)
+                       for ( i = 0 ; i < w->numpoints ; i++ )
                        {
-                               fprintf (pf,"(");
-                               WriteFloat (pf, w->p[i][0]);
-                               WriteFloat (pf, w->p[i][1]);
-                               WriteFloat (pf, w->p[i][2]);
-                               fprintf (pf,") ");
+                               fprintf( pf,"(" );
+                               WriteFloat( pf, w->p[i][0] );
+                               WriteFloat( pf, w->p[i][1] );
+                               WriteFloat( pf, w->p[i][2] );
+                               fprintf( pf,") " );
                        }
-                       fprintf (pf,"\n");
+                       fprintf( pf,"\n" );
                }
        }
 
 }
 
+void CountSolidFaces_r( node_t *node ){
+       int s;
+       portal_t    *p;
+       winding_t   *w;
+
+       // decision node
+       if ( node->planenum != PLANENUM_LEAF ) {
+               CountSolidFaces_r( node->children[0] );
+               CountSolidFaces_r( node->children[1] );
+               return;
+       }
+
+       if ( node->opaque ) {
+               return;
+       }
+
+       for ( p = node->portals ; p ; p = p->next[s] )
+       {
+               w = p->winding;
+               s = ( p->nodes[1] == node );
+               if ( w ) {
+                       if ( PortalPassable( p ) ) {
+                               continue;
+                       }
+                       if ( p->nodes[0]->cluster == p->nodes[1]->cluster ) {
+                               continue;
+                       }
+                       // write out to the file
+
+                       ++num_solidfaces;
+               }
+       }
+}
+
 /*
-=================
-WriteFaceFile_r
-=================
-*/
-void WriteFaceFile_r (node_t *node)
-{
-       int                     i, s;   
-       portal_t        *p;
-       winding_t       *w;
+   =================
+   WriteFaceFile_r
+   =================
+ */
+void WriteFaceFile_r( node_t *node ){
+       int i, s;
+       portal_t    *p;
+       winding_t   *w;
 
        // decision node
-       if (node->planenum != PLANENUM_LEAF) {
-               WriteFaceFile_r (node->children[0]);
-               WriteFaceFile_r (node->children[1]);
+       if ( node->planenum != PLANENUM_LEAF ) {
+               WriteFaceFile_r( node->children[0] );
+               WriteFaceFile_r( node->children[1] );
                return;
        }
-       
-       if (node->opaque) {
+
+       if ( node->opaque ) {
                return;
        }
 
-       for (p = node->portals ; p ; p=p->next[s])
+       for ( p = node->portals ; p ; p = p->next[s] )
        {
                w = p->winding;
-               s = (p->nodes[1] == node);
-               if (w)
-               {
-                       if (PortalPassable(p))
+               s = ( p->nodes[1] == node );
+               if ( w ) {
+                       if ( PortalPassable( p ) ) {
+                               continue;
+                       }
+                       if ( p->nodes[0]->cluster == p->nodes[1]->cluster ) {
                                continue;
+                       }
                        // write out to the file
 
-                       if (p->nodes[0] == node)
-                       {
-                               fprintf (pf,"%i %i ",w->numpoints, p->nodes[0]->cluster);
-                               for (i=0 ; i<w->numpoints ; i++)
+                       if ( p->nodes[0] == node ) {
+                               fprintf( pf,"%i %i ",w->numpoints, p->nodes[0]->cluster );
+                               for ( i = 0 ; i < w->numpoints ; i++ )
                                {
-                                       fprintf (pf,"(");
-                                       WriteFloat (pf, w->p[i][0]);
-                                       WriteFloat (pf, w->p[i][1]);
-                                       WriteFloat (pf, w->p[i][2]);
-                                       fprintf (pf,") ");
+                                       fprintf( pf,"(" );
+                                       WriteFloat( pf, w->p[i][0] );
+                                       WriteFloat( pf, w->p[i][1] );
+                                       WriteFloat( pf, w->p[i][2] );
+                                       fprintf( pf,") " );
                                }
-                               fprintf (pf,"\n");
+                               fprintf( pf,"\n" );
                        }
                        else
                        {
-                               fprintf (pf,"%i %i ",w->numpoints, p->nodes[1]->cluster);
-                               for (i = w->numpoints-1; i >= 0; i--)
+                               fprintf( pf,"%i %i ",w->numpoints, p->nodes[1]->cluster );
+                               for ( i = w->numpoints - 1; i >= 0; i-- )
                                {
-                                       fprintf (pf,"(");
-                                       WriteFloat (pf, w->p[i][0]);
-                                       WriteFloat (pf, w->p[i][1]);
-                                       WriteFloat (pf, w->p[i][2]);
-                                       fprintf (pf,") ");
+                                       fprintf( pf,"(" );
+                                       WriteFloat( pf, w->p[i][0] );
+                                       WriteFloat( pf, w->p[i][1] );
+                                       WriteFloat( pf, w->p[i][2] );
+                                       fprintf( pf,") " );
                                }
-                               fprintf (pf,"\n");
+                               fprintf( pf,"\n" );
                        }
                }
        }
 }
 
 /*
-================
-NumberLeafs_r
-================
-*/
-void NumberLeafs_r (node_t *node)
-{
-       portal_t        *p;
-
+   ================
+   NumberLeafs_r
+   ================
+ */
+void NumberLeafs_r( node_t *node, int c ){
+#if 0
+       portal_t    *p;
+#endif
        if ( node->planenum != PLANENUM_LEAF ) {
                // decision node
                node->cluster = -99;
-               NumberLeafs_r (node->children[0]);
-               NumberLeafs_r (node->children[1]);
+
+               if ( node->has_structural_children ) {
+#if 0
+                       if ( c >= 0 ) {
+                               Sys_FPrintf( SYS_ERR,"THIS CANNOT HAPPEN\n" );
+                       }
+#endif
+                       NumberLeafs_r( node->children[0], c );
+                       NumberLeafs_r( node->children[1], c );
+               }
+               else
+               {
+                       if ( c < 0 ) {
+                               c = num_visclusters++;
+                       }
+                       NumberLeafs_r( node->children[0], c );
+                       NumberLeafs_r( node->children[1], c );
+               }
                return;
        }
-       
+
        node->area = -1;
 
        if ( node->opaque ) {
@@ -217,44 +313,53 @@ void NumberLeafs_r (node_t *node)
                return;
        }
 
-       node->cluster = num_visclusters;
-       num_visclusters++;
+       if ( c < 0 ) {
+               c = num_visclusters++;
+       }
+
+       node->cluster = c;
 
+#if 0
        // count the portals
-       for (p = node->portals ; p ; )
+       for ( p = node->portals ; p ; )
        {
-               if (p->nodes[0] == node)                // only write out from first leaf
-               {
-                       if (PortalPassable(p))
+               if ( p->nodes[0] == node ) {      // only write out from first leaf
+                       if ( PortalPassable( p ) ) {
                                num_visportals++;
-                       else
+                       }
+                       else{
                                num_solidfaces++;
+                       }
                        p = p->next[0];
                }
                else
                {
-                       if (!PortalPassable(p))
+                       if ( !PortalPassable( p ) ) {
                                num_solidfaces++;
-                       p = p->next[1];         
+                       }
+                       p = p->next[1];
                }
        }
+#endif
 }
 
 
 /*
-================
-NumberClusters
-================
-*/
-void NumberClusters(tree_t *tree) {
+   ================
+   NumberClusters
+   ================
+ */
+void NumberClusters( tree_t *tree ) {
        num_visclusters = 0;
        num_visportals = 0;
        num_solidfaces = 0;
 
-       Sys_FPrintf (SYS_VRB,"--- NumberClusters ---\n");
-       
+       Sys_FPrintf( SYS_VRB,"--- NumberClusters ---\n" );
+
        // set the cluster field in every leaf and count the total number of portals
-       NumberLeafs_r (tree->headnode);
+       NumberLeafs_r( tree->headnode, -1 );
+       CountVisportals_r( tree->headnode );
+       CountSolidFaces_r( tree->headnode );
 
        Sys_FPrintf( SYS_VRB, "%9d visclusters\n", num_visclusters );
        Sys_FPrintf( SYS_VRB, "%9d visportals\n", num_visportals );
@@ -262,31 +367,28 @@ void NumberClusters(tree_t *tree) {
 }
 
 /*
-================
-WritePortalFile
-================
-*/
-void WritePortalFile (tree_t *tree)
-{
-       char    filename[1024];
-
-       Sys_FPrintf (SYS_VRB,"--- WritePortalFile ---\n");
-       
+   ================
+   WritePortalFile
+   ================
+ */
+void WritePortalFile( tree_t *tree, const char *portalFilePath ){
+
+       Sys_FPrintf( SYS_VRB,"--- WritePortalFile ---\n" );
+
        // write the file
-       sprintf (filename, "%s.prt", source);
-       Sys_Printf ("writing %s\n", filename);
-       pf = fopen (filename, "w");
-       if (!pf)
-               Error ("Error opening %s", filename);
-               
-       fprintf (pf, "%s\n", PORTALFILE);
-       fprintf (pf, "%i\n", num_visclusters);
-       fprintf (pf, "%i\n", num_visportals);
-       fprintf (pf, "%i\n", num_solidfaces);
-
-       WritePortalFile_r(tree->headnode);
-       WriteFaceFile_r(tree->headnode);
-
-       fclose (pf);
-}
+       Sys_Printf( "writing %s\n", portalFilePath );
+       pf = fopen( portalFilePath, "w" );
+       if ( !pf ) {
+               Error( "Error opening %s", portalFilePath );
+       }
+
+       fprintf( pf, "%s\n", PORTALFILE );
+       fprintf( pf, "%i\n", num_visclusters );
+       fprintf( pf, "%i\n", num_visportals );
+       fprintf( pf, "%i\n", num_solidfaces );
 
+       WritePortalFile_r( tree->headnode );
+       WriteFaceFile_r( tree->headnode );
+
+       fclose( pf );
+}