home *** CD-ROM | disk | FTP | other *** search
/ PC PowerPlay 58 / pcpp58a.iso / extras / quake 3 source / Q3A_ToolSource.exe / Main / writebsp.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-01-02  |  7.4 KB  |  398 lines

  1. #include "qbsp.h"
  2.  
  3. /*
  4. ============
  5. EmitShader
  6. ============
  7. */
  8. int    EmitShader( const char *shader ) {
  9.     int                i;
  10.     shaderInfo_t    *si;
  11.  
  12.     if ( !shader ) {
  13.         shader = "noshader";
  14.     }
  15.  
  16.     for ( i = 0 ; i < numShaders ; i++ ) {
  17.         if ( !Q_stricmp( shader, dshaders[i].shader ) ) {
  18.             return i;
  19.         }
  20.     }
  21.  
  22.     if ( i == MAX_MAP_SHADERS ) {
  23.         Error( "MAX_MAP_SHADERS" );
  24.     }
  25.     numShaders++;
  26.     strcpy( dshaders[i].shader, shader );
  27.  
  28.     si = ShaderInfoForShader( shader );
  29.     dshaders[i].surfaceFlags = si->surfaceFlags;
  30.     dshaders[i].contentFlags = si->contents;
  31.  
  32.     return i;
  33. }
  34.  
  35.  
  36. /*
  37. ============
  38. EmitPlanes
  39.  
  40. There is no oportunity to discard planes, because all of the original
  41. brushes will be saved in the map.
  42. ============
  43. */
  44. void EmitPlanes (void)
  45. {
  46.     int            i;
  47.     dplane_t    *dp;
  48.     plane_t        *mp;
  49.  
  50.     mp = mapplanes;
  51.     for (i=0 ; i<nummapplanes ; i++, mp++)
  52.     {
  53.         dp = &dplanes[numplanes];
  54.         VectorCopy ( mp->normal, dp->normal);
  55.         dp->dist = mp->dist;
  56.         numplanes++;
  57.     }
  58. }
  59.  
  60.  
  61.  
  62. /*
  63. ==================
  64. EmitLeaf
  65. ==================
  66. */
  67. void EmitLeaf (node_t *node)
  68. {
  69.     dleaf_t                *leaf_p;
  70.     bspbrush_t            *b;
  71.     drawSurfRef_t        *dsr;
  72.  
  73.     // emit a leaf
  74.     if (numleafs >= MAX_MAP_LEAFS)
  75.         Error ("MAX_MAP_LEAFS");
  76.  
  77.     leaf_p = &dleafs[numleafs];
  78.     numleafs++;
  79.  
  80.     leaf_p->cluster = node->cluster;
  81.     leaf_p->area = node->area;
  82.  
  83.     //
  84.     // write bounding box info
  85.     //    
  86.     VectorCopy (node->mins, leaf_p->mins);
  87.     VectorCopy (node->maxs, leaf_p->maxs);
  88.     
  89.     //
  90.     // write the leafbrushes
  91.     //
  92.     leaf_p->firstLeafBrush = numleafbrushes;
  93.     for ( b = node->brushlist ; b ; b = b->next ) {
  94.         if ( numleafbrushes >= MAX_MAP_LEAFBRUSHES ) {
  95.             Error( "MAX_MAP_LEAFBRUSHES" );
  96.         }
  97.         dleafbrushes[numleafbrushes] = b->original->outputNumber;
  98.         numleafbrushes++;
  99.     }
  100.     leaf_p->numLeafBrushes = numleafbrushes - leaf_p->firstLeafBrush;
  101.  
  102.     //
  103.     // write the surfaces visible in this leaf
  104.     //
  105.     if ( node->opaque ) {
  106.         return;        // no leaffaces in solids
  107.     }
  108.     
  109.     // add the drawSurfRef_t drawsurfs
  110.     leaf_p->firstLeafSurface = numleafsurfaces;
  111.     for ( dsr = node->drawSurfReferences ; dsr ; dsr = dsr->nextRef ) {
  112.         if ( numleafsurfaces >= MAX_MAP_LEAFFACES)
  113.             Error ("MAX_MAP_LEAFFACES");
  114.         dleafsurfaces[numleafsurfaces] = dsr->outputNumber;
  115.         numleafsurfaces++;            
  116.     }
  117.  
  118.  
  119.     leaf_p->numLeafSurfaces = numleafsurfaces - leaf_p->firstLeafSurface;
  120. }
  121.  
  122.  
  123. /*
  124. ============
  125. EmitDrawNode_r
  126. ============
  127. */
  128. int EmitDrawNode_r (node_t *node)
  129. {
  130.     dnode_t    *n;
  131.     int        i;
  132.  
  133.     if (node->planenum == PLANENUM_LEAF)
  134.     {
  135.         EmitLeaf (node);
  136.         return -numleafs;
  137.     }
  138.  
  139.     // emit a node    
  140.     if (numnodes == MAX_MAP_NODES)
  141.         Error ("MAX_MAP_NODES");
  142.     n = &dnodes[numnodes];
  143.     numnodes++;
  144.  
  145.     VectorCopy (node->mins, n->mins);
  146.     VectorCopy (node->maxs, n->maxs);
  147.  
  148.     if (node->planenum & 1)
  149.         Error ("WriteDrawNodes_r: odd planenum");
  150.     n->planeNum = node->planenum;
  151.  
  152.     //
  153.     // recursively output the other nodes
  154.     //    
  155.     for (i=0 ; i<2 ; i++)
  156.     {
  157.         if (node->children[i]->planenum == PLANENUM_LEAF)
  158.         {
  159.             n->children[i] = -(numleafs + 1);
  160.             EmitLeaf (node->children[i]);
  161.         }
  162.         else
  163.         {
  164.             n->children[i] = numnodes;    
  165.             EmitDrawNode_r (node->children[i]);
  166.         }
  167.     }
  168.  
  169.     return n - dnodes;
  170. }
  171.  
  172. //=========================================================
  173.  
  174.  
  175.  
  176. /*
  177. ============
  178. SetModelNumbers
  179. ============
  180. */
  181. void SetModelNumbers (void)
  182. {
  183.     int        i;
  184.     int        models;
  185.     char    value[10];
  186.  
  187.     models = 1;
  188.     for ( i=1 ; i<num_entities ; i++ ) {
  189.         if ( entities[i].brushes || entities[i].patches ) {
  190.             sprintf ( value, "*%i", models );
  191.             models++;
  192.             SetKeyValue (&entities[i], "model", value);
  193.         }
  194.     }
  195.  
  196. }
  197.  
  198. /*
  199. ============
  200. SetLightStyles
  201. ============
  202. */
  203. #define    MAX_SWITCHED_LIGHTS    32
  204. void SetLightStyles (void)
  205. {
  206.     int        stylenum;
  207.     const char    *t;
  208.     entity_t    *e;
  209.     int        i, j;
  210.     char    value[10];
  211.     char    lighttargets[MAX_SWITCHED_LIGHTS][64];
  212.  
  213.  
  214.     // any light that is controlled (has a targetname)
  215.     // must have a unique style number generated for it
  216.  
  217.     stylenum = 0;
  218.     for (i=1 ; i<num_entities ; i++)
  219.     {
  220.         e = &entities[i];
  221.  
  222.         t = ValueForKey (e, "classname");
  223.         if (Q_strncasecmp (t, "light", 5))
  224.             continue;
  225.         t = ValueForKey (e, "targetname");
  226.         if (!t[0])
  227.             continue;
  228.         
  229.         // find this targetname
  230.         for (j=0 ; j<stylenum ; j++)
  231.             if (!strcmp (lighttargets[j], t))
  232.                 break;
  233.         if (j == stylenum)
  234.         {
  235.             if (stylenum == MAX_SWITCHED_LIGHTS)
  236.                 Error ("stylenum == MAX_SWITCHED_LIGHTS");
  237.             strcpy (lighttargets[j], t);
  238.             stylenum++;
  239.         }
  240.         sprintf (value, "%i", 32 + j);
  241.         SetKeyValue (e, "style", value);
  242.     }
  243.  
  244. }
  245.  
  246. //===========================================================
  247.  
  248. /*
  249. ==================
  250. BeginBSPFile
  251. ==================
  252. */
  253. void BeginBSPFile( void ) {
  254.     // these values may actually be initialized
  255.     // if the file existed when loaded, so clear them explicitly
  256.     nummodels = 0;
  257.     numnodes = 0;
  258.     numbrushsides = 0;
  259.     numleafsurfaces = 0;
  260.     numleafbrushes = 0;
  261.  
  262.     // leave leaf 0 as an error, because leafs are referenced as
  263.     // negative number nodes
  264.     numleafs = 1;
  265. }
  266.  
  267.  
  268. /*
  269. ============
  270. EndBSPFile
  271. ============
  272. */
  273. void EndBSPFile( void ) {
  274.     char    path[1024];
  275.  
  276.     EmitPlanes ();
  277.     UnparseEntities ();
  278.  
  279.     // write the map
  280.     sprintf (path, "%s.bsp", source);
  281.     _printf ("Writing %s\n", path);
  282.     WriteBSPFile (path);
  283. }
  284.  
  285.  
  286. //===========================================================
  287.  
  288. /*
  289. ============
  290. EmitBrushes
  291. ============
  292. */
  293. void EmitBrushes ( bspbrush_t *brushes ) {
  294.     int                j;
  295.     dbrush_t        *db;
  296.     bspbrush_t        *b;
  297.     dbrushside_t    *cp;
  298.  
  299.     for ( b = brushes ; b ; b = b->next ) {
  300.         if ( numbrushes == MAX_MAP_BRUSHES ) {
  301.             Error( "MAX_MAP_BRUSHES" );
  302.         }
  303.         b->outputNumber = numbrushes;
  304.         db = &dbrushes[numbrushes];
  305.         numbrushes++;
  306.  
  307.         db->shaderNum = EmitShader( b->contentShader->shader );
  308.         db->firstSide = numbrushsides;
  309.  
  310.         // don't emit any generated backSide sides
  311.         db->numSides = 0;
  312.         for ( j=0 ; j<b->numsides ; j++ ) {
  313.             if ( b->sides[j].backSide ) {
  314.                 continue;
  315.             }
  316.             if ( numbrushsides == MAX_MAP_BRUSHSIDES ) {
  317.                 Error( "MAX_MAP_BRUSHSIDES ");
  318.             }
  319.             cp = &dbrushsides[numbrushsides];
  320.             db->numSides++;
  321.             numbrushsides++;
  322.             cp->planeNum = b->sides[j].planenum;
  323.             cp->shaderNum = EmitShader( b->sides[j].shaderInfo->shader );
  324.         }
  325.     }
  326.  
  327. }
  328.  
  329.  
  330. /*
  331. ==================
  332. BeginModel
  333. ==================
  334. */
  335. void BeginModel( void ) {
  336.     dmodel_t    *mod;
  337.     bspbrush_t    *b;
  338.     entity_t    *e;
  339.     vec3_t        mins, maxs;
  340.     parseMesh_t    *p;
  341.     int            i;
  342.  
  343.     if ( nummodels == MAX_MAP_MODELS ) {
  344.         Error( "MAX_MAP_MODELS" );
  345.     }
  346.     mod = &dmodels[nummodels];
  347.  
  348.     //
  349.     // bound the brushes
  350.     //
  351.     e = &entities[entity_num];
  352.  
  353.     ClearBounds (mins, maxs);
  354.     for ( b = e->brushes ; b ; b = b->next ) {
  355.         if ( !b->numsides ) {
  356.             continue;    // not a real brush (origin brush, etc)
  357.         }
  358.         AddPointToBounds (b->mins, mins, maxs);
  359.         AddPointToBounds (b->maxs, mins, maxs);
  360.     }
  361.  
  362.     for ( p = e->patches ; p ; p = p->next ) {
  363.         for ( i = 0 ; i < p->mesh.width * p->mesh.height ; i++ ) {
  364.             AddPointToBounds( p->mesh.verts[i].xyz, mins, maxs );
  365.         }
  366.     }
  367.  
  368.     VectorCopy (mins, mod->mins);
  369.     VectorCopy (maxs, mod->maxs);
  370.  
  371.     mod->firstSurface = numDrawSurfaces;
  372.     mod->firstBrush = numbrushes;
  373.  
  374.     EmitBrushes( e->brushes );
  375. }
  376.  
  377.  
  378.  
  379.  
  380. /*
  381. ==================
  382. EndModel
  383. ==================
  384. */
  385. void EndModel( node_t *headnode ) {
  386.     dmodel_t    *mod;
  387.  
  388.     qprintf ("--- EndModel ---\n");
  389.  
  390.     mod = &dmodels[nummodels];
  391.     EmitDrawNode_r (headnode);
  392.     mod->numSurfaces = numDrawSurfaces - mod->firstSurface;
  393.     mod->numBrushes = numbrushes - mod->firstBrush;
  394.  
  395.     nummodels++;
  396. }
  397.  
  398.